Università degli Studi di Torino
Ennio Davide Isaia
Linguaggio R e applicazioni statistiche
a.a. 2000-2001
Dipartimento di Statistica e Matematica Applicata “Diego de Castro”
È senza dubbio inevitabile che questi appunti presentino errori materiali;
Sarò grato a tutti coloro, e specialmente agli Studenti, che vorranno segnalarci qualunque problema, dai più banali errori tipografici alle oscurità
nell’esposizione.
Avvertenza
Tutti i diritti di questa pubblicazione sono degli autori.
Viene consentita la riproduzione integrale di questa pubblicazione a titolo gratuito. Altresı̀ è permessa, sempre a titolo gratuito, l’utilizzazione di parti di questa pubblicazione in altra opera all’inderogabile condizione che ne venga citata
la provenienza e che della nuova opera nella sua interezza vengano consentite la riproduzione integrale a titolo gratuito e l’utilizzazione di parti a queste
stesse condizioni. L’uso di questa pubblicazione in qualsiasi forma comporta
l’accettazione integrale e senza riserve di quanto sopra.
Dipartimento di Statistica e Matematica Applicata “Diego de Castro”
Corso Unione Sovietica, 218/bis
10134, Torino (Italy)
c 2000–2009
�
Capitolo 1
Introduzione ad R
R, parente di S-Plus ed erede di S, è un ambiente integrato che consente di elaborare
dati, eseguire calcoli e creare rappresentazioni grafiche; dotato di un linguaggio di
programmazione ad alto livello, con esso è possibile eseguire operazioni assai complesse
con poche linee di comandi e, pertanto, si dimostra uno strumento estremamente
potente che permette di analizzare e risolvere problemi specifici attinenti a diversi
settori scientifici.
Le sue caratteristiche peculiari, ai fini statistici, sono rappresentate dalla possibilità
di elaborazione di grandi quantità di dati, la vasta disponibilità di operatori per il
calcolo matriciale e vettoriale nonché l’enorme disponibilità di librerie (“package”)
matematiche, statistiche e grafiche.
R, inoltre, è un software completamente gratuito e continuamente aggiornato, disponibile per piattaforme Unix (FreeBSD, NetBSD, Linux, Irix, Solaris, OSF/1, AIX,
HPUX), Windows 9x/NT nonché MacOS. La URL ufficiale per il progetto R è:
http://www.r-project.org
dove è possibile prelevare l’ultima versione di R, un manuale ufficiale di riferimento a
cura del R Core Team (2000) nonché una vasta gamma di “packages” aggiuntivi; un’interessante lista di “Frequently Asked Questions”, The R FAQ a cura di Kurt Hornik,
è reperibile all’indirizzo http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html.
Una volta acquisito il programma e prescindendo dall’installazione/compilazione a
seconda della piattaforma di destinazione, l’applicativo ed altri file, tra cui .Renviron
saranno raccolti in un’unica directory, ad esempio <drive>\...\R Home Directory,
la quale, a sua volta, conterrà altre directory, tra le quali:
• \library: contenente le librerie (“package”) di base nonché quelle di interesse
per l’utente, ad esempio:
\library\base
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
\library\ctest
...
\library\modreg
nelle quali sono posti i file, in formato ACII, CONTENTS, DESCRIPTION, INDEX
e TITLE; inoltre, ciascuna di esse ha una struttura comune, articolata in altre
directory tra cui citiamo:
– \R: contenente il file sorgente, in formato ACII, delle funzioni definite per
il “package” stesso;
– \data: contenente alcuni archivi di dati a cui viene spesso fatto riferimento
nelle finestre di “help” di R stesso.
– \help: contenente, in formato compresso (.zip, .tar, ...) i file di help in
linea;
– \html, \latex: ove sono posti i file di help in formato html e LATEX.
• \doc: contenente, organizzati in corrispondenti sotto-directory, alcuni documenti di aiuto.
A tal proposito è bene tenere a mente che essenziale ai fini di un corretto funzionamento dell’applicativo è la presenza del “package” base, contenente in \library\base\R il
file di definizione dei principali comandi (base), nonché il file Rprofile di definizione
dell’ambiente di lavoro.
1.1
L’ambiente di lavoro
Una volta lanciato il programma compare la finestra R GUI 1 , dove potranno essere
impartiti i comandi e saranno visualizzati i risultati delle elaborazioni o gli eventuali
messaggi di errore; tale finestra dispone di menu (File, Edit, Misc, Windows, Help)
autoesplicativi.
Nel seguito lavoreremo unicamente attreverso la finestra R GUI, cioè impartiremo,
dopo il classico prompt >, i comandi in sequenza oppure li sottoporremo in modalità
“batch”.
All’avvio R GUI mostra alcune informazioni, quali la versione di R che si sta usando
ed alcuni comandi chiave per iniziare o chiudere una sessione di lavoro.
Un comando, a cui ci abitueremo, è help(argomento); ad esempio help() chiede
ad R di aprire una nuova finestra che contiene una breve guida in linea dal titolo
1
Sotto Unix compare la finestra R Console, il cui aspetto è piuttosto spartanto. Sotto MacOS e
Linux-ppc comapre la fienstra R Console, delt tutto analoga alla finestra R GUI che caratterizza i
sistemi Windows9x/NT e Linux.
2
E. D. Isaia, Linguaggio R e applicazioni statistiche
“R Information”. Tale finestra offre una descrizione dettagliata del comando e, più
importante, riporta in fondo una serie di esempi che, mediante “copia e incolla”,
possono essere inseriti sulla Console.
Un secondo comando utile per avvicinarsi ad R è demo(), il quale, a seconda della
versione installata, potrebbe porgere:
> demo()
Use ‘demo(topic)’ where choices for argument ‘topic’ are:
topics
[1,] "graphics"
[2,] "image"
[3,] "lm.glm"
[4,] "glm.vr"
[5,] "nlm"
[6,] "recursion"
[7,] "scoping"
[8,] "is.things"
[9,] "dyn.load"
In sostanza R suggerisce di utilizzare il comando nella forma demo(topics), dove
topic è uno degli argomenti proposti; ad esempio demo(graphics).
Una terza finestra disponibile è la Graphics Window ove verranno visualizzati, appunto, i grafici via via richiesti. Questa abitualmente non viene aperta all’avvio
di R, ma viene attivata allorché si impartisce un comando che prevede un output grafico. L’utente può in ogni caso forzare la sua attivazione con il comando
X11(), windows() o macintosh() a seconda della piattaforma Unix, Windows9x/NT
o MacOS rispettivamente.
È bene tenere a mente che per default l’area di lavoro corrisponde alla directory
\R Home Directory; tale situazione può essere modificata in qualsiasi istante ricorendo al comando setwd(<directory>). Cosı̀, ad esempio, immaginando un’installazione su piattaforma Windows, potremmo avere:
> getwd()
[1] "C:\Programs\R"
> setwd("C:\Progetti")
NULL
> getwd()
[1] "C:\Progetti"
> setwd(R.home())
NULL
> getwd()
3
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
[1] "C:\Programs\R"
Al momento di abbandonare R, ci viene richiesto se desideriamo registrare quanto
svolto nella corrente sessione di lavoro:
> q()
Save workspace image? [y/n/c]:
In caso affermativo, l’intero “workspace” verrà registrato, per default, sul file Rdata;
in tal modo sarà possibile “ritornare al punto” semplicemente lancianto R tramite
Rdata.
1.2
Primi passi in R
Le entità con cui lavora R vengono dette oggetti; questi vengono identificati tramite
un nome, a discrezione dell’utente, che deve iniziare con un carattere alfabetico e non
può contenere spazi bianchi nè i caratteri @, #, $, _, mentre è ammesso l’uso del punto
(.) quale separatore tra i caratteri.
Se gli elementi di un oggetto presentano tutti la stessa modalità, numerica, alfanumerica, logica oppure complessa, l’oggetto stesso viene detto elementare. Tali oggetti, a
loro volta, possono essere dotati di una struttura di matrice, e ciò nel senso algebrico
del termine, oppure possono concorrere a creare quelli che nel seguito chiameremo
oggetti complessi.
Ciò premesso, dedichiamo i paragrafi che seguono alla descrizione di come definire e
manipolare oggetti con struttura elementare, di matrice o complessa ed eseguire su
di essi alcune semplici operazioni, ricorrendo a funzioni predefinite ovvero creadone
altre ad hoc.
1.2.1
Creazione di oggetti elementari
La creazione di un qualsiasi oggetto avviene ricorrendo al comando di assegnazione
<- e non, come è norma abituale con altri linguaggi di programmazione, tramite
il simbolo =, a cui segue, in linea di massima, entro parentesi tonde precedute dal
prefisso c, acronimo di combine, l’elenco dei suoi elementi, ciasuno dei quali separato
da una virgola. Qualora l’oggetto possedesse modalità alfanumerica, il suoi elementi
debbono essere racchiusi entro virgolette (").
Ciò premesso, la visualizzazione degli elementi di un oggetto può avvenire digitandone
il nome oppure, in fase di definizione, racchiudendone l’istruzione entro parentesi
tonde.
Esempio 1.2.1 Ci proponiamo di creare tre oggetti elementari e di visualizzarne il contenuto;
più precisamente:
4
E. D. Isaia, Linguaggio R e applicazioni statistiche
— x contenente il solo elemento numerico 17:
> x<-c(17)
> x
[1] 17
— y i cui elementi corrispondono agli interi 10, 13, 17, 20:
> (y<-c(10,13,17,20))
[1] 10 13 17 20
— alpha che conterrà tre caratteri alfanumerici
> (alpha<-c("Valor medio","Mediana","Varianza"))
[1] "Valor medio" "Mediana"
"Varianza"
♥
A questo punto, possiamo introdurre le seguenti istruzioni di utilità assai generale:
• ls(): visualizza l’elenco degli oggetti definiti in una sessione di lavoro 2 .
• ls.str(): porge un breve“resoconto” circa la struttura degli oggetti definiti
nella corrente sessione di lavoro. Informazioni dettagliate circa uno specifico
oggetto, si ottengono con il comando str(oggetto);
• mode(oggetto): restituisce, sottoforma di stringa, la modalità dell’oggetto
indicato;
• rm(oggetto1, ...,oggetton): consente la rimozione degli oggetti specificati.
Desiderando rimuovere tutti gli oggetti definiti nel corso di una sessione di lavoro
si può ricorrere all’istruzione rm(list=ls()). La rimozione del solo contenuto
di un oggetto avviene tramite l’assegnazione oggetto<-NULL
Esempio 1.2.2 Con riferimento ai tre oggetti introdotti all’Esempio 1.2.1, si osservi il comportamento, autoesplicativo, delle istruzioni:
> ls.str()
alpha : chr [1:3] "Valor medio" "Mediana" "Varianza"
x : num 17
y : num [1:4] 10 13 17 20
> mode(alpha)
[1] "character"
> (y<-NULL)
2
In alternativa si può ricorrere al comando objects().
5
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
NULL
> ls()
[1] "alpha" "x"
> rm(x)
> ls()
[1] "alpha" "y"
> rm(y,alpha)
> ls()
character(0)
"y"
♥
Può a volte capitare di volere elencare (o rimuovere) solo alcuni degli oggetti definiti
durante una sessione di lavoro; ciò avviene ricorrendo all’opzione pattern=, propria
dei comandi ls(), rm() e ls.str(). A tal riguardo, si osservi il comportamento delle
istruzioni:
> C02<-c(0.011,0.012,0.013,0.012)
> fattoreA<-c(1,2,1,2)
> fattoreB<-c(1,2,1,2)
> ls()
[1] "C02"
"fattoreA"
"fattoreB"
> ls.str(pattern="fat")
fattoreA : num [1:4] 1 2 1 2
fattoreB : num [1:4] 1 2 1 2
> rm(list=ls(pattern="fat"))
> ls()
[1] "C02"
L’opzione pattern=, come la maggior parte delle opzioni R, può essere abbreviata,
qualora non sussistano ambiguità, ai primi tre caratteri; nel seguito tuttavia, per
motivi di chiarezza espositiva, ricorreremo sempre alla forma estesa.
1.2.2
Creazione di oggetti contenenti sequenze regolari
La creazione di oggetti contenenti “sequenze regolari” di elementi numerici o alfanumerici può avvenire ricorrendo ai comandi:
• c(n1:n2): crea una sequenza di interi consecutivi da n1 a n2, in ordine crescente
se n1 < n2, in ordine decrescente altrimenti;
• seq(n1,n2,by=passo): crea una sequenza di numeri consecutivi da n1 a n2 con
incrementi pari a quanto specificato in passo, in ordine crescente se n1 < n2, in
6
E. D. Isaia, Linguaggio R e applicazioni statistiche
ordine decrescente altrimenti. Qualora l’opzione by=passo fosse omessa e n1 e
n2 fossero interi, l’istruzione verrebbe ad essere equivalente a c(n1:n2). Un’alternativa a by= è rappresentata dall’opzione length=, con la quale si stabilisce
appunto la lunghezza della sequenza o, meglio, il numero dei suoi elementi;
• rep(k:n): crea un oggetto contenente i valori, numerici o alfanumerici, specificati in k ripetuti n volte;
• letters[k:n] o LETTERS[k:n]: creano una sequenza di lettere, minuscole e
maiuscole rispettivamente, dell’alfabeto latino comprese tra k ed n.
Altri comandi specifici, quali gl(), expand.grid(), ppoints() e sequence(), verranno presentati al paragrafo 1.2.6.
Esempio 1.2.3 Creazione e visualizzazione dell’oggetto x che conterrà i primi dieci interi
positivi:
> (x<-c(1:10))
[1] 1 2 3 4
5
6
7
8
9 10
Si noti che saremmo giunti allo stesso risultato ricorrendo all’istruzione seq():
> (x<-seq(1,10))
[1] 1 2 3 4 5
6
7
8
9 10
♥
Esempio 1.2.4 Creazione e visualizzazione dell’oggetto x che conterrà 11 numeri progressivi
da 20 a 21 con passo 0.10:
> (x<-seq(20,21,by=0.10))
[1] 20.0 20.1 20.2 20.3 20.4 20.5 20.6 20.7 20.8 20.9 21.0
Allo stesso risultato saremmo pervenuti con il comando:
> (x<-seq(20,21,length=11))
[1] 20.0 20.1 20.2 20.3 20.4 20.5 20.6 20.7 20.8 20.9 21.0
♥
Esempio 1.2.5 Creazione dell’oggetto x che conterrà, nell’ordine, 3 elementi a valore nullo
e 4 elementi a valore unitario.
> (x<-c(rep(0,3),rep(1,4)))
[1] 0 0 0 1 1 1 1
7
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
♥
Esempio 1.2.6 Visualizzazione delle stringhe "Conforme" e "Difettoso" ripetute la prima
tre volte e la seconda una sola volta:
> c(rep("Conforme",3),rep("Difettoso",1))
[1] "Conforme" "Conforme" "Conforme" "Difettoso"
♥
Esempio 1.2.7 Creazione e visualizzazione dell’oggetto alfabeto che conterrà le prime sette
lettere, in minuscolo, dell’alfabeto (latino):
> (alfabeto<-letters[1:7])
[1] "a" "b" "c" "d" "e" "f" "g"
Si osservi il comportamento delle istruzioni:
> LETTERS[1:7]
[1] "A" "B" "C" "D" "E" "F" "G"
> paste(letters[1:3],sep="",collapse="+")
[1] "a+b+c"
> paste("Fattore",letters[1:3],sep="",collapse="+")
[1] "Fattorea+Fattoreb+Fattorec"
♥
1.2.3
Manipolazione di oggetti elementari
In R esistono svariati comandi che consentono la manipolazione di oggetti, numerici
o alfanumerici; tra essi val qui la pena citare i seguenti di utilità generale:
• append(x,y): aggiunge agli elementi dell’oggeto x gli elementi di y;
• c(x,y): crea un nuovo oggetto a partire da due oggetti x e y;
• paste(x,y): crea un un nuovo oggetto contenente, sottoforma alfanumerica,
gli elementi appaiati degli oggetti x e y; l’opzione sep="simbolo" consente di separare i diversi elementi con il simbolo desiderato, mentre l’opzione
collapse="simbolo" permette di separare i singoli risultati con il simbolo
prescelto;
• rev(x): posiziona in senso inverso gli elementi di x;
• sort(x): ordina in senso crescente gli elementi di x; altrimenti;
8
E. D. Isaia, Linguaggio R e applicazioni statistiche
• unique(x): restituisce gli elementi non ripetuti contenuti in x.
• x[posizione1,..,posizionen]: estrae dall’oggeto x gli elementi che occupano
la posizione specificata in posizione1,..,posizionen;
Altri comandi verranno presentati al paragrafo 1.2.6.
Esempio 1.2.8 Ordinamento in senso crescente degli elementi di x<-c(10:1):
> sort(x)
[1] 1 2
3
4
5
6
7
8
9 10
5
6
7
8
9 10
o, equivalentemente:
> rev(x)
[1] 1 2
3
4
A proposito di rev(), si noti che:
> rev(c(10,11,9))
[1] 9 11 10
e ciò coerentemente con quanto detto a proposito.
♥
Esempio 1.2.9 Creazione di un nuovo oggetto a partire da due oggetti definiti:
> x<-c(1:5)
> y<-rev(x)
> (z<-c(x,y))
[1] 1 2 3 4 5 5 4 3 2 1
♥
Esempio 1.2.10 Creazione, a partire da due oggetti, di un nuovo oggetto che contiene,
sottoforma alfanumerica, gli elementi appaiati degli oggetti iniziali.
> x<-c(1:5)
> y<-c(-5:-1)
> paste(x,y)
[1] "1 -5" "2 -4" "3 -3" "4 -2" "5 -1"
Si ossservi che, coerentemente:
> paste(x)
[1] "1" "2" "3" "4" "5"
Si noti, ancora, il comportamento dei seguenti comandi:
9
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> paste(y,x,sep="*")
[1] "-5*1" "-4*2" "-3*3" "-2*4" "-1*5"
> paste(y,x,sep="*",collapse="<->")
[1] "-5*1<->-4*2<->-3*3<->-2*4<->-1*5"
♥
Esempio 1.2.11 Estrazione dall’oggetto x, che contiene gli interi consecutivi da 1 a 20, degli
elementi che occupano la terza e la dodicesima posizione.
> x<-c(1:20)
> x[3]
[1] 3
> x[12]
[1] 12
♥
Esempio 1.2.12 Creazione, a partire dall’oggetto x, che contiene gli interi consecutivi da
10 a 20, dell’oggetto y che conterrà i tre elementi che occupano la prima, la terza e la sesta
posizione in x.
> (x<-c(10:20))
[1] 10 11 12 13 14 15 16 17 18 19 20
> (y<-x[c(1,3,6)] )
[1] 10 12 15
♥
Esempio 1.2.13 Creazione dell’oggetto z che conterrà, nell’ordine, i primi tre elementi di x,
i due elementi di y quindi i restanti elementi di x.
> (x<-c(10:17))
[1] 10 11 12 13 14 15 16 17
> (y<-c(300,400))
[1] 300 400
> (z<-append(x, y, after=3))
[1] 10 11 12 300 400 13
14
15
16
17
♥
Esempio 1.2.14 Eliminazione ed ordinamento crescente degli elementi ripetuti di un oggetto.
> (x<-c(c(5:8),c(1:7)))
[1] 5 6 7 8 1 2 3 4 5 6 7
> sort(unique(x))
[1] 1 2 3 4 5 6 7 8
10
E. D. Isaia, Linguaggio R e applicazioni statistiche
♥
Esempio 1.2.15 Creazione, a partire dall’oggetto x che contiene 3 elementi a valore nullo e 4
elementi a valore unitario, dell’oggetto sesso che conterrà l’etichetta Femmina se x=0 oppure
Maschio se x=1.
> (x<-c(rep(0,3),rep(1,4)))
[1] 0 0 0 1 1 1 1
> (sex<-c(rep("Femmina",3),rep("Maschio",4)))
[1] "Femmina" "Femmina" "Femmina" "Maschio" "Maschio" "Maschio" "Maschio"
Un’alternativa è offerta dal ricorso al comando names(); ad esempio:
> (x<-c(rep(0,3),rep(1,4)))
[1] 0 0 0 1 1 1 1
> (names(x)<-c(rep("Femmina",3),rep("Maschio",4)))
[1] "Femmina" "Femmina" "Femmina" "Maschio" "Maschio" "Maschio" "Maschio"
Per maggiori dettagli sul comando names(), cfr. paragrafo 1.2.6.
1.2.4
♥
Operatori aritmetici e funzioni matematiche
Sugli oggetti elementari con modalità numerica è possible eseguire le più comuni operazioni aritmetiche, quali la somma (+), il prodotto (*), la divisione (/), l’elevamento
a potenza (^), proprie di un qualsiasi linguaggio di programmazione.
Esempio 1.2.16 Dati i due oggetti x e y ad elemeti numerici:
> x<-seq(1:5)
> y<-x^2
le istruzioni che seguono si commentano da sè:
> x-(1/y)
[1] 0.000000 1.750000 2.888889 3.937500 4.960000
> 100*(x+y)^(-1)
[1] 50.000000 16.666667 8.333333 5.000000 3.333333
> y^(.5)+x
[1] 2 4 6 8 10
♥
Vale qui la pena accennare alla presenza di due particolari operatori, %% e %/%, il cui
impiego, a volte utile, è illustrato dagli esempi che seguono.
Esempio 1.2.17 Posto che l’oggetto x contenga gli interi consecutivi da 1 a 10, ci proponiamo
di:
11
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
— individuare quali di essi è divisibile per 2. A tal fine possiamo considerare il comando
x%%2 che porge il resto della divisione di ciascun elemento di x per 2:
> x<-c(1:10)
> x%%2
[1] 1 0 1 0 1 0 1 0 1 0
— calcolare la parte intera della divisione tra ciascun elemento di x e 2. A tal fine
sopperisce il comando x%/%2, infatti:
> x<-c(1:10)
> x%/%2
[1] 0 1 1 2 2 3 3 4 4 5
Quanto alle funzioni matematiche, tra le quali figurano exp(), log(), log10(),
log2(),..., sin(), cos(), tan(), asin(), acos(), atan(), sqrt(), abs()..., è impensabile offrirne qui un’elenco seppur parziale; alcune di esse, di interesse sotto il
profilo statistico, sono presentate al paragrafo che segue, mentre altre ancora saranno
introdotte più oltre allorché verranno affrontati problemi specifici.
Accenniamo, infine, alla presenza di particolari funzioni che cosentono di eseguire le
più comuni operazioni su insiemi:
• union(x,y): restituisce l’insieme costituito dall’unione degli insiemi x e y;
• intersect(x,y): restituisce l’insieme costituito dall’intersezione degli insiemi
x e y;
• setdiff(x,y): rstituisce l’insieme costituito dalla differenza tra insiemi x e y;
• setequal(x,y): restituisce il valore logico TRUE se gli insiemi contengono gli
stessi elementi, il valore logico FALSE altrimenti;
• is.element(el,set): restituisce il valore logico TRUE se l’elemento in el è
contenuto in set, il valore logico FALSE altrimenti. Un alias del comando è
%in%.
Esempio 1.2.18 Definiti gli oggetti A<-letters[1:4] e B<-letters[3:7], abbiamo:
> union(A,B)
[1] "a" "b" "c" "d" "e" "f" "g"
> intersect(A,B)
[1] "c" "d"
> setdiff(A,B)
[1] "a" "b"
> setdiff(B,A)
12
E. D. Isaia, Linguaggio R e applicazioni statistiche
[1] "e" "f" "g"
> is.element(A,setdiff(A,B))
[1] TRUE TRUE FALSE FALSE
> "f"%in%union(A,B)
[1] TRUE
> is.element("q",setdiff(letters[1:24],union(A,B)))
[1] TRUE
Si noti che tali operatori in ogni caso rimuovono gli elementi duplicati di un insieme.
1.2.5
♥
Su alcune funzioni statistiche
Tra le innumerevoli funzioni statistiche implementate, per il momento ci limitiamo
a citare le più comuni e precisamente, posto x un’oggetto elementare con modalità
numerica:
• cumsum(x): restituisce la somma cumulata degli elementi di x;
• length(x): restituisce il numero degli elementi 3 contneuti in x;
• max(x), min(oggetto): porgono, rispettivamente, il massimo ed il minimo dei
valori contenuti in x;
• mean(x): calcola la media aritmetica dei valori contenuti in x;
• median(x): calcola la mediana dei valori contenuti in x;
• prod(x): restituisce il prodotto degli elementi di x;
• quantile(x,alpha): porge il quantile di ordine alpha degli elementi di x;
• sum(x): restituisce la somma degli elementi di x;
• summary(x): visualizza4 il minimo, il primo quartile, la media aritmetica, la
mediana, il terzo quartile ed il massimo degli elementi di x;
• table(x): porge la distribuzione di frequenze assolute generata dalle osservazioni individuali registrate in x;
• var(x) e sd(x): calcolano, rispettivamente, la varianza e lo scarto quadratico
medio dei valori contenuti in x. È bene ricordare, sin da ora, che la varianza, e
di conseguenza lo scarto quadratico medio, è calcolata come:
n
1 !
(xi − µx )2
n − 1 i=1
3
4
A bene vedere trattasi di una funzione “primitiva” di impiego assai generale.
Tale è il suo comportamento se applicata ad un oggetto numerico elemementare.
13
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
quindi con un numero di gradi di libertà pari a length(x)-1. Tale grandezza
viene abitualmente detta varianza campionaria.
• weighted.mean(xi,ni): calcola la media aritmetica dei valori contenuti in xi
con pesi ni.
Esempio 1.2.19 Si immagini che la rilevazione il voto conseguito all’esame di Statistica,
espresso in trentesimi, conseguito da un gruppo di 20 studenti abbia fornito i risultati:
18
27
23
25
30
27
25
23
27
30
27
25
30
23
20
20
20
25
25
23
Definito l’oggetto elementare voti.stat:
> voti.stat<-c(18,23,30,25,27,27,30,20,20,25,27,25,27,23,30,25,23,20,25,23)
facilmente possiamo ottenere:
— la distribuzione dei voti in termini di frequenze assolute:
> table(voti.stat)
voti.stat
18 20 23 25 27 30
1 3 4 5 4 3
nonché relative:
> table(voti.stat)/length(voti.stat)
voti.stat
18
20
23
25
27
30
0.05 0.15 0.20 0.25 0.20 0.15
Si osservi che, dal momento che table(voti.stat) restituisce un oggetto numerico, la
media dei voti potrebbe essere calcolata ricorrendo all’istruzione:
> weighted.mean(sort(unique(voti.stat)),table(voti.stat)/20)
[1] 24.65
— alcune misure di tendenza centrale:
% > summary(voti.stat)
%
Min. 1st Qu. Median
%
18.00
23.00
25.00
Mean 3rd Qu.
24.65
27.00
Max.
30.00
Visto che summary(voti.stat) restituisce un oggetto composto da sei elementi, possiamo ottenere la differenza interquartilica come:
14
E. D. Isaia, Linguaggio R e applicazioni statistiche
> summary(voti.stat)[5]-summary(voti.stat)[2]+.
— la varianza campionaria nonché la devianza:
> var(voti.stat)
[1] 12.02895
> var(voti.stat)*(length(voti.stat)-1)
[1] 228.55
♥
1.2.6
Alcune funzioni di utilità generale
Dedichiamo questo paragrafo alla presentazione di alcune funzioni, oltre a quelle già
citate, a cui spesso può essere fatto ricorso durante una sessione di lavoro.
• abbreviate(oggetto, mln=, dot=FALSE): abbrevia gli elementi dell’oggetto
specificato al una lunghezza minima pari a mln=. Ponendo dot=TRUE viene
visualizzato il suffisso “.”. Ad esempio:
> x<-c("Ennio","Davide","Isaia")
> abbreviate(x[1:2], minl=1)
Ennio Davide
"E"
"D"
> abbreviate(x[1:2], minl=1,dot=TRUE)
Ennio Davide
"E."
"D."
• all(oggetto) consente di confrontare tutti gli elementi di un oggetto rispetto
ad una condizione. Ad esempio:
> x<-c(-2.2,-1.8,-1.5,-1.4,-1.2,-1.0,-0.9,-0.8,-0.7 ,0.2)
> all(x>0)
[1] FALSE
Il suo complemento è la funzione any(oggetto).
> x<-c(-2.2,-1.8,-1.5,-1.4,-1.2,-1.0,-0.9,-0.8,-0.7 ,0.2)
> any(x>0)
[1] TRUE
15
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
• all.names(expression) e all.vars(expression) porgono, rispettivamente,
gli elementi e le variabili che compaiono nell’espressione indicata e definita via
expression() o quote().
• append(oggetto, valori, after=posizione): aggiunge gli elementi contenuti in valori all’oggetto specificato, eventualmente nella posizione desiderata.
Ad esempio:
> x<-integer(0)
> (x<-append(x,1:10))
[1] 1 2 3 4 5 6 7 8 9 10
> (x<-append(x,120,after=2))
[1]
1
2 120
3
4
5
6
7
8
9
10
Si osservi che la situazione di default prevede after=length(x).
Tale comando può tornare utile qualora si desideri inserire in un oggetto gli
elementi via, via generati da specifiche funzioni.
• attr(oggetto,attributo): attribuisce all’oggetto indicato un particolare “attributo”. Ad esempio:
> x<-c(1:10)
> attr(x,"dim")<-c(2, 5)
> x
[,1] [,2] [,3] [,4] [,5]
[1,]
1
3
5
7
9
[2,]
2
4
6
8
10
> attr(x,"dim")<-NULL
> x
[1] 1 2 3 4 5 6 7 8 9 10
• cat(): acronimo di “concatenate & print” trasforma gli elementi indicati quale
argomento in strighe alfanumeriche e li visualizza. Il suffisso "\n" consente al
cursore di ritornare in modalità “prompt” (>). Ad esempio:
> x<-c(1,2,3)
> a<-c("degli elementi di x")
> cat("La media ",a," e’:",sum(x)/length(x),"\n")
La media degli elementi di x e’: 2
>
16
E. D. Isaia, Linguaggio R e applicazioni statistiche
• date(): restituisce, sottoforma alfanumerica, la data di sistema.
> date()
[1] "Tue Aug 28 05:16:51 2001"
• deparse(oggetto): trasforma la definizione dell’oggetto specificiato in una
stringa. Cosı̀, ad esempio:
> a<-letters[1:3]
> deparse(a)
[1] "c(\"a\", \"b\", \"c\")"
• diff(oggetto,lag=): calcola le differenze tra i diversi elementi di un oggetto.
Ad esempio:
> diff(c(10,23,21,30),1)
[1] 13 -2 9
• duplicated(oggetto): indica, in forma logica, quali elementi dell’oggetto specificato quale argomento sono ripetuti. Ad esempio:
> x<-c(1:4)
> y<-c(2:6)
> duplicated(c(paste(x),paste(rev(y))))
[1] FALSE FALSE FALSE FALSE FALSE FALSE TRUE
TRUE
TRUE
• eval(funzione): calcola il valore la funzione specificata in corrispondenza a
determinati valori di interesse. Quali esempi, valgano le seguenti istruzioni:
> eval(3 ^ 2 ^ 3)
[1] 6561
> eval(sin(.25*pi)+cos(.25*pi))
[1] 1.414214
> sin(.25*x)+cos(2*.25*x)
Error: Object "x" not found
> x<-pi/2
> sin(.25*x)+cos(2*.25*x)
[1] 1.089790
17
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Si vedano anche i comportamenti delle funzioni expression() e quote().
• expand.grid(x,y,z,...): crea un “data frame” (cfr. paragrafo 1.4.2) contenente tutte le combinazioni degli elementi dei vettori (o fattori) x, y, z, ...
specificati. Ad esempio:
> expand.grid(temperatura=seq(100,120,10),pressione=seq(1,2,1))
temperatura pressione
1
100
1
2
110
1
3
120
1
4
100
2
5
110
2
6
120
2
• expression(funzione): restituisce l’espressione di una funzione senza provvedere al calcolo automatico. Si ossservi il comportamento delle istruzioni:
> (fx<-expression(x^2+2*x))
expression(x^2 + 2 * x)
> eval(fx)
Error in eval(expr, envir, enclos) : Object "x" not found
> x<-seq(-1,1)
> eval(fx)
[1] -1 0 3
> all.names(expression(sin(x+y)))
[1] "sin" "+"
"x"
"y"
> all.vars(expression(sin(x+y)))
[1] "x" "y"
Si veda anche il comportamento della funzione quote().
• factor(oggetto,levels=(n1,...,nn)): definisce in modo diretto l’oggetto
specificato quale fattore a n livelli. Un’alternativa è il ricorso a as.factor(oggetto).
Sono, pertanto, comandi validi:
> (temperatura<-factor(c(1,1,1,2,2,2),levels=c(1:2)))
[1] 1 1 1 2 2 2
Levels: 1 2
> trattamento<-c("A","B","B","A","B","A","C","C","C")
18
E. D. Isaia, Linguaggio R e applicazioni statistiche
> (trattamento<-as.factor(trattamento))
[1] A B B A B A C C C
Levels: A B C
• format(oggetto,...): attribuisce all’oggetto specificato un formato per una
migliore visualizzazione dei suoi elementi. Per default il comando prevede l’allineamento a destra, justify="right", e un numero di decimali pari a quanto
definito (cfr. paragrafo 1.9) in getOption("digits"). A commento:
> (x<-c(2,15,21,25)/3)
[1] 0.6666667 5.0000000 7.0000000 8.3333333
> format(x,digits=3)
[1] "0.667" "5.000" "7.000" "8.333"
> format(x^3,digits=3,justify="right")
[1] " 0.296" "125.000" "343.000" "578.704"
> alpha<-c("Valor medio","Mediana","Varianza")
> format(alpha,justify="left")
[1] "Valor medio" "Mediana
" "Varianza
"
> format(alpha,justify="right")
[1] "Valor medio" "
Mediana" "
Varianza"
> format(alpha,justify="none")
[1] "Valor medio" "Mediana"
"Varianza"
• formula("espressione"): consente di definire un nuovo oggetto con struttura
tipo formula il cui impiego è principalmente riservato alle procedure di regressione (lm) e di analisi della varianza (aov). La trasformazione della struttura di
un’opportuna stringa in formula avviene con il comando as.formula(striga).
Alcuni esempi sono:
>
y
>
>
y
(formulayx<-formula("y~x"))
~ x
nomi.x<-paste("x",c(1:4),sep="")
(f<-as.formula(paste("y ~ ", paste(nomi.x, collapse= "+"))))
~ x1 + x2 + x3 + x4
• gl(n,k): genera in modo automatico una sequenza di interi positivi da 1 a n,
ciascuno dei quali viene ripetuto k volte 5 . Il risultato ha struttura factor. Ad
esempio:
5
Si noti che length(gl(n,k))=n*k.
19
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> (temperatura<-gl(2,3))
[1] 1 1 1 2 2 2
Levels: 1 2
L’opzione labels =, che per default viene posta uguale a 1:n, consente di attribuire, a discrezione dell’utente, etichette ai diversi livelli del fattore di interesse;
ad esempio:
> (temperatura<-gl(2,3,labels=c(120,160)))
[1] 120 120 120 160 160 160
Levels: 120 160
> (sesso<-gl(2,3,labels=c("Maschio","Femmina")))
[1] Maschio Maschio Maschio Femmina Femmina Femmina
Levels: Maschio Femmina
• levels(fattore): indica quali sono i livelli del fattore specificato. Infatti:
> temperatura<-gl(2,3,labels=c(120,160))
> sesso<-gl(2,3,labels=c("Maschio","Femmina"))
> levels(temperatura)
[1] "120" "160"
> levels(sesso)
[1] "Maschio" "Femmina"
• match(x,y,nomatch=NA): confronta i due oggetti x e y e restituisce l’elenco degli
elementi della loro intersezione. Gli elementi diversi sono, per default, definiti
mancanti (NA). Ad esempio:
> x<-c(1:10)
> y<-c(7:20)
> match(x,y)
[1] NA NA NA NA NA NA
1
2
3
mentre:
> y[match(x,y,nomatch=0)]
[1] 7 8 9 10
20
4
E. D. Isaia, Linguaggio R e applicazioni statistiche
• names(oggetto): trattasi di un comando assai generale che, essenzialmente,
consente di attribuire etichette ai diversi elementi di un oggetto. A tal proposito,
si immagini che x contenga 5 elementi numerici di cui tre a valori 0 e due a
valore 1 e che si desideri attribuire l’etichetta Maschio qualora x=0 e Femmina
altrimenti; le istruzioni necessarie sono:
> (x<-sort(c(0,1,0,1,1)))
[1] 0 0 1 1 1
> (names(x)<-c(rep("Maschio",3),rep("Femmina",2)))
[1] "Maschio" "Maschio" "Maschio" "Femmina" "Femmina"
L’eliminazione delle etichette attribuite ad un’oggetto avviene con il comando
names(oggetto)<-NULL.
Si osservi che il semplice comando names(oggetto) consente di visualizzare
le etichette associate all’oggetto specificato e, come vedremo nel seguito (cfr.
paragrafi 1.4.1 e 1.4.2), qualora l’oggetto fosse una “lista” o un “data frame” ne
elencherebbe i nomi degli elementi.
• nchar(oggetto): restituisce il numero di caratteri di ciascun elemento alfanumerico contenuto nell’oggetto specificato. Cosı̀:
> a<-c("sommatoria","produttoria")
> nchar(a)
[1] 10 11
> sum(nchar(a))
[1] 21
• noquote(oggetto): visualizza gli elementi dell’oggetto alfanumerico specificato
senza racchiuderli entro le consuete virgolette.
> noquote(c(letters[1:4],rev(letters[1:4])))
[1] a b c d d c b a
• ppoints(n): genera una sequenza di n numeri in accordo a (1:n-.5)/n. Quale
argomento è possibile indicare un oggetto numerico.
> ppoints(6)
[1] 0.10 0.26 0.42 0.58 0.74 0.90
21
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Tale funzione torna utile, ad esempio, per individuare i quantili di una distribuzione.
• pretty(oggetto,n=): restituisce una sequenza di n numeri tali da suddividere
il range dell’oggetto specificato in altrettanti intervalli di egual ampiezza. A
commento:
> x<-c(10,10.5,11,12,13,13.5,16.5,17,18,20)
> pretty(x,n=2)
[1] 10 15 20
> pretty(x)
[1] 10 12 14 16 18
• quote(oggetto): restituisce l’espressione di una funzione senza provvedere al
calcolo automatico. Si ossservi il comportamento delle istruzioni:
> (f<-quote((2*pi)^(-.5)*exp(-.5*x^2)))
(2 * pi)^(-0.5) * exp(-0.5 * x^2)
> x<-c(-1,0,1)
> eval(f)
[1] 0.2419707 0.3989423 0.2419707
• replace(oggetto,posizione,valori): rimpiazza gli elementi dell’oggetto specificato nella posizione indicata con i valori elencati o con gli elementi di un
secondo oggetto. Ad esempio:
> x<-seq(1:10)
> y<-c(100,120)
> replace(x,2:3,y)
[1]
1 100 120
4
5
6
7
8
9
10
• round(oggetto,decimali): trasforma gli elementi dell’oggetto ad elementi numerici indicato in numeri con tante cifre decimali quante specificate in decimali:
> round(seq(1:10)/seq(1,2,length=10),2)
[1] 1.00 1.80 2.45 3.00 3.46 3.86 4.20 4.50 4.76 5.00
• sequence(n1:nmax): crea delle sequenze di numeri interi del tipo:
n1 , n1 , n2 , n1 , n2 , n3 , . . . , n1 , n2 , . . . , nmax
A tal proposito:
22
E. D. Isaia, Linguaggio R e applicazioni statistiche
> sequence(1:5)
[1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
> sequence(5:1)
[1] 1 2 3 4 5 1 2 3 4 1 2 3 1 2 1
• sign(oggetto): ricodifica in -1, 0 e 1 gli elementi numerici dell’oggetto specificato a seconda che essi siano, rispettivamente, negativi, nulli o positivi.
> (x<-c(seq(-3,2)))
[1] -3 -2 -1 0 1 2
> sign(x)
[1] -1 -1 -1 0 1 1
> sign(abs(x))
[1] 1 1 1 0 1 1
• substr(oggetto,start,stop): trasforma gli elementi dell’oggetto alfanumerico indicato in strighe con un mumero di caratteri compresi tra start e stop;
ad esempio:
> (x<-c("Varianza","Devianza"))
[1] "Varianza" "Devianza"
> substr(x,1,3)
[1] "Var" "Dev"
> rev(substr(x, 1,3))
[1] "Dev" "Var"
Per completezza, riportiamo i seguenti tre comandi di utilità:
• apropos(what,mode="any"): porge un elenco di tutti gli oggetti i cui nomi
contengono quanto specificato in what e ciò, per default, indipendentemente
dalla loro modalità (mode="any"):
> apropos(integrate)
[1] "integrate"
"print.integrate"
Si badi che digitando apropos(".") si otterrebbe l’elenco completo di tutti
gli oggetti predefiniti in R, che sono ben 1456 (length(apropos("."))); di
questi quelli che poseggono modalità di tipo "function" risultano essere 1453
(length(apropos(".",mode="function"))).
23
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
• exists("oggetto",mode="any"): controlla l’esistenza dell’oggetto specificato,
indipendentemente dalla sua modalità; il risultato è di tipo logico:
> exists("integrate")
[1] TRUE
> exists("f")
[1] FALSE
> f<-expression(x+2*x^2)
> exists("f",mode="function")
[1] TRUE
• find(what,mode="any"): riporta il nome della librebria in cui si trova l’oggetto
indicati in what:
> find(cor)
[1] "package:base"
> find(cor.test)
[1] "package:ctest"
1.3
Vettori e Matrici
Appare del tutto naturale, ora, dedicare la nostra attenzione alla creazione e la manipolazione di oggetti che hanno struttura di vettore o di matrice e ciò secondo la
comune accezione dell’algebra lineare.
È comunque bene tenere a mente che abitualmente nel linguaggio informatico una
qualsiasi stringa di caratteri (numerici o alfanumerici) viene detta vettore. Tutti gli
oggetti definiti in R sono dunque vettori, a meno che non abbiano struttura di matrice
(cfr. paragrafo 1.5).
I principali comandi, nella forma più semplice, che utilizzeremo nel seguito per definire
e manipolare matrici algebriche sono:
• array(oggetto,dim=c(nrow,ncol)): trasforma l’oggetto indicato in una matrice di ordine nrow×ncol (cfr. Osservazione 1.3.1);
• cbind(oggetto): trasforma l’oggetto indicato in un vettore colonna;
• matrix(oggetto,nrow=,ncol=): trasforma l’oggetto indicato in una matrice
di ordine nrow×ncol;
• rbind(oggetto): trasforma l’oggetto indicato in un vettore riga;
24
E. D. Isaia, Linguaggio R e applicazioni statistiche
Per comodità di esposizione, a fine paragrafo, riassumiamo in modo ordinato le
principali funzioni predefinite che operano su oggetti con struttura, appunto, di
matrice.
Esempio 1.3.1 Creazione e visualizzazione del vettore riga x e del vettore colonna y che
conterranno, entrambi, i primi quattro interi positivi:
> (x<-rbind(c(1:4)))
[,1] [,2] [,3] [,4]
[1,]
1
2
3
4
> (y<-cbind(c(1:4)))
[,1]
[1,]
1
[2,]
2
[3,]
3
[4,]
4
Un’alternativa potrebbe essere la seguente:
> x<-matrix(c(1:4),nrow=1,ncol=4)
> y<-matrix(c(1:4),nrow=4,ncol=1)
I precedenti comandi che definiscono le matrici x e y potrebbero essere scritti in forma compatta, omettendo cioè gli identificativi nrow= e ncol=, ricordando che il numero delle righe
dve precedere quello delle colonne; in sostanza avremmo potuto impartire i comandi:
> x<-matrix(c(1:4),1,4)
> y<-matrix(c(1:4),4,1)
Nel seguito tuttavia, per motivi di chiarezza espositiva, ricorreremo sempre alla forma estesa
del comando.
♥
Esempio 1.3.2 Creazione della matrice X le cui righe corrispondono ai vettori x e y sudefiniti:
> (X<-rbind(x,t(y)))
[,1] [,2] [,3] [,4]
[1,]
1
2
3
4
[2,]
1
2
3
4
Si osservi che il comando t(y) porge la trasposta del vettore (colonna) y, infatti:
> t(y)
[,1] [,2] [,3] [,4]
[1,]
1
2
3
4
♥
25
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
"
#
Esempio 1.3.3 Creazione dell’oggetto z, contenente gli elementi del vettore x = 1 2 3 .
È sufficiente ricorrere all’istruzione drop(), infatti:
> (x<-rbind(c(1:3)))
[,1] [,2] [,3]
[1,]
1
2
3
> z<-drop(x)
> z
[1] 1 2 3
♥
Esempio 1.3.4 Creazione e visualizzazione della matrice X le cui quattro colonne contengono,
in progressione, gli interi da 1 a 12:
> (X<-matrix(c(1:12),nrow=3,ncol=4))
[,1] [,2] [,3] [,4]
[1,]
1
4
7
10
[2,]
2
5
8
11
[3,]
3
6
9
12
Un’alternativa potrebbe essere la seguente:
> X<-c(1:12)
> dim(X)<-c(3,4)
oppure:
> Y<-array(c(1:12),dim=c(3,4))
♥
Osservazione 1.3.1 Il comando array() è assai versatile; con esso, ad esempio si
possono creare matrici, per cosı̀ dire, “a più dimensioni”.
A tal proposito si immagini di volere creare due matrici, di ordine 3 × 3 ciascuna e
contenenti gli interi da 1 a 9 e da 10 a 18 rispettivamente, da inserire in un’unico
oggetto, Y con struttura di matrice. Ciò può avvenire tramite il comando:
> (Y<-array(c(1:18),dim=c(3,3,2)))
, , 1
[,1] [,2] [,3]
[1,]
1
4
7
[2,]
2
5
8
[3,]
3
6
9
26
E. D. Isaia, Linguaggio R e applicazioni statistiche
, , 2
[1,]
[2,]
[3,]
[,1] [,2] [,3]
10
13
16
11
14
17
12
15
18
Esempio 1.3.5 Data la matrice:


1 2 1
A = 4 3 2
1 2 1
( (
ci proponiamo di calcolare 32 21 aij . In R, gli elementi aij della matrice A vengono individuati con la notazione A[i,j], dove A è una matrice definita mentre i e j sono gli indici che ne identificano rispetttivamente le righe e le colonne, e quindi i=1,...,nrow(A) e
j=1,...,ncol(A).
Il calcolo indicato potrebbe essere risolto, perlomeno in prima battuta , come:
> A<-matrix(c(1,4,1,2,3,2,1,2,1),nrow=3,ncol=3)
> A[2,1]+A[2,2]+A[3,1]+A[3,2]
[1] 10
A tal proposito, cfr. Esempio 1.3.14.
♥
Esempio 1.3.6 Data la matrice:
A=
)
1 2 3
5 6 7
*
ne estraiamo i due vettori riga e i tre vettori colonna.
In R la notazione A[1,] e A[,1] indicano, rispettivamente, gli oggetti costituiti dagli elementi
della prima riga e, rispettivamente, della prima colonna di A. Ciò premesso, possiamo pensare
di risolvere il problema mediante le istruzioni:
>
>
>
>
>
>
A<-matrix(c(1,5,2,6,3,7),nrow=2,ncol=3)
riga1<-rbind(A[1,])
riga2<-rbind(A[2,])
col1<-cbind(A[,1])
col2<-cbind(A[,2])
col3<-cbind(A[,3])
infatti, ad esempio:
27
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> riga1
[,1] [,2] [,3]
[1,]
1
2
3
> col2
[,1]
[1,]
2
[2,]
6
♥
Esempio 1.3.7 Posto che Y sia una matrice contenente, a sua volta, due matrici di ordine
3 × 3 ciascuna (cfr. Osservazione 1.3.1 ed Esempio 1.3.6), ci proponiamo di estrarre da essa:
— le singole matrici:
> (Y[,,1])
[,1] [,2] [,3]
[1,]
1
4
7
[2,]
2
5
8
[3,]
3
6
9
> (Y[,,2])
[,1] [,2] [,3]
[1,]
10
13
16
[2,]
11
14
17
[3,]
12
15
18
— il vettore corrispondente alla prima riga della prima matrice ed il vettore corrispondente
alla prima colonna della seconda matrice:
> (rbind(Y[1,,1]))
[,1] [,2] [,3]
[1,]
1
4
7
> (cbind(Y[,1,2]))
[,1]
[1,]
10
[2,]
11
[3,]
12
♥
Esempio 1.3.8 Costruzione della matrice A di ordine 4 × 4 con elementi nulli tranne sulla
diagonale principale ove compaiono, in successione, i primi quattro interi. In sostanza dovrà
essere aij = 0 per i #= j e aij = i per i = j e i = 1, 2, 3, 4.
Desiderando procedere, possiamo pensare di creare la matrice A ad elementi nulli e succesivamente rimpiazzare gli elementi della sua diagonale principale, cioè quelli per cui risulta 6
row(A) ==col(A), con gli interi 1,2,3,4. In effetti:
6
Si osservi il ricorso al simbolo ==; cfr. il paragrafo 1.6.
28
E. D. Isaia, Linguaggio R e applicazioni statistiche
> A<-matrix(0,nrow=4,ncol=4)
> A[row(A) == col(A)]<-c(1:4)
> A
[,1] [,2] [,3] [,4]
[1,]
1
0
0
0
[2,]
0
2
0
0
[3,]
0
0
3
0
[4,]
0
0
0
4
Un’alternativa ci è offerta dal ricorso alla funzione diag() che porge gli elementi della diagonale principale della matrice indicata quale argomento; in tal caso
> A<-matrix(0,nrow=4,ncol=4)
> diag(A)<-c(1:4)
> A
[,1] [,2] [,3] [,4]
[1,]
1
0
0
0
[2,]
0
2
0
0
[3,]
0
0
3
0
[4,]
0
0
0
4
Desiderando, quindi, costruire una matrice identità di dimensione n × n saranno sufficienti le
istruzioni:
> X<-matrix(0,nrow=n,ncol=n)
> diag(X)<-c(1)
lasciandone al Lettore la verifica sul campo.
♥
Esempio 1.3.9 Data la matrice:


1 2 3
A = 4 1 5
6 7 1
definiamo due vettori riga, diciamo x e y, contenenti rispettivamente gli elementi posti alla
sinistra e alla destra della diagonale principale di A.
Se osserviamo che gli elementi aij di A che giacciono a sinistra della diagonale sono quelli
per cui i > j, cioè row(A)>col(A), mentre quelli che stanno alla destra della stessa saranno
quelli per cui i < j, cioè row(A)<col(A), abbiamo:
> A<-matrix(c(1,4,6,2,1,7,3,5,1),nrow=3,ncol=3)
> x<-rbind(A[row(A) > col(A)])
> y<-rbind(A[row(A) < col(A)])
ed infatti:
29
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> x
[1,]
> y
[1,]
[,1] [,2] [,3]
4
6
7
[,1] [,2] [,3]
2
3
5
♥
Esempio 1.3.10 Dati i vettori:
) *
"
#
3
x=
y= 1 2
5
è noto che:
x·y =
)
3 6
5 10
*
x · y = 13 = xt · yt
In R impartiremo le istruzioni:
> x<-rbind(3,5)
> y<-cbind(1,2)
> x%*%y
[,1] [,2]
[1,]
3
6
[2,]
5
10
> y%*%x
[,1]
[1,]
13
Il prodotto tra vettori e/o matrici viene quindi introdotto mediante l’operatore %*%.
Si noti che, coerentemente:
> t(x)%*%y
Error in x %*% t(y) : non-conformable arguments
♥
Esempio 1.3.11 Ci proponiamo di risolvere il sistema di equazioni:
+
2x+y = 7
x+2y = 8
Riscritto il sistema in forma matriciale:
)
*) * ) *
x
2 1
7
−1
y = 8 → Ax = b → x = A b
1 2
in R impartiremo le istruzioni:
30
E. D. Isaia, Linguaggio R e applicazioni statistiche
>
>
>
>
A<-matrix(c(2,1,1,2),nrow=2,ncol=2)
b<-cbind(c(7,8))
x<-solve(A)%*%b
x
[,1]
[1,]
2
[2,]
3
o equivalentemente:
>
>
>
>
A<-matrix(c(2,1,1,2),nrow=2,ncol=2)
b<-cbind(c(7,8))
x<-solve(A,b)
x
[,1]
[1,]
2
[2,]
3
♥
Esempio 1.3.12 Costruzione di matrice che contiene gli elementi di una semplice “tabella
pitagorica” per gli interi da 1 a 4. Sono sufficienti le istruzioni:
> x<-cbind(c(1:4))
> matrix(outer(x,x,"*"),4,4)
[,1] [,2] [,3] [,4]
[1,]
1
2
3
4
[2,]
2
4
6
8
[3,]
3
6
9
12
[4,]
4
8
12
16
Al Lettore l’interpretazione dell’output dell’istruzione matrix(outer(x,x,"^"),4,4).
♥
Esempio 1.3.13 Calcolo delle somme di riga e di colonna della matrice:


30 25 20 15
A =  5 10 15 20 
3 7 10 15
Definita la matrice:
> A<-matrix(c(30,5,3,25,10,7,20,15,10,15,20,15),nrow=3,ncol=4)
i totali di riga e di colonna possono essere ottenuti applicando a ciascuna riga e colonna
l’operatore sum(), cioè impartendo le istruzioni:
31
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> sum(A[1,]); sum(A[2,]); sum(A[3,])
> sum(A[,1]); sum(A[,2]); sum(A[,3]); sum(A[,4])
Un’alternativa consiste nel ricorso alla funzione7 apply(.,.,.) i cui argomenti sono, nell’ordine: la matrice su cui operare, l’identificativo per i vettori riga o colonna (1=righe, 2=colonne),
nonché la funzione che si desidera applicare, nel caso in esame sum. Pertanto:
> apply(A, 1, sum)
[1] 90 50 35
> apply(A, 2, sum)
[1] 38 42 45 50
Proprio sulla funzione apply() è basata la funzione margin.table(.,.), i cui argomenti sono
la matrice di interesse e l’identificativo numerico per i vettori riga o colonna, che porge i totali
desiderati; infatti:
> margin.table(A,1)
[1] 90 50 35
> margin.table(A,2)
[1] 38 42 45 50
Osservazione 1.3.2 È bene ricordare che, data una matrice Ar,s , cioè di ordine r × s, ed
indicando con 1α un generico vettore riga unitario di ordine α si ha:
r
!
i=1
aij = 1r Ar,s
s
!
aij =
r !
s
!
Ar,s 1ts
i=1
aij = 1r Ar,s 1ts
i=1 j=1
Cosı̀, ad esempio, nel caso della matrice A proposta:
>
>
>
>
>
>
>
A<-matrix(c(30,5,3,25,10,7,20,15,10,15,20,15),nrow=3,ncol=4)
br<-rbind(c(rep(1,nrow(A))))
bs<-rbind(c(rep(1,ncol(A))))
tot.col<-br%*%A
tot.riga<-A%*%t(bs)
tot<-br%*%A%*%t(bs)
tot.col
[,1] [,2] [,3] [,4]
[1,]
38
42
45
50
> tot.riga
[,1]
[1,]
90
[2,]
50
[3,]
35
> tot
[,1]
[1,] 175
7
Funzioni strettamente legate ad apply() sono tapply() (Esempio ??) e sapply() (Esempio ??).
32
E. D. Isaia, Linguaggio R e applicazioni statistiche
Si noti che i risultati richiesti risultano sottoforma di vettori.
Esempio 1.3.14 Data la matrice:


1 2 1
A = 4 3 2
1 2 1
calcoliamo
abbiamo:
(3 (2
2
1
aij . Anziché operare come illustrato all’Esempio 1.3.5, in modo diretto
> sum(A[c(2:3),c(1:2)])
[1] 10
♥
A conclusione del paragrafo, ci pare utile proporre un semplice elenco delle principali
funzioni predefinite che operano su oggetti con struttura di matrice.
Con riferimento ad una generica matrice Y si ha:
• aperm(Y,k): consente di effetturare una permutazione di Y rispetto all’argomento k. Evidentemente con aperm(Y) si ha la trasposta di Y;
• det(Y): calcola il determinante della matrice quadrata Y in accordo all’algoritmo
QR (cfr. Esempio 1.6.7);
• diag(Y): porge gli elementi della diagonale principale di Y;
• diag(k): definisce una matrice identità di ordine (kxk);
• eigen(Y): fornisce in forma di “lista” (cfr. 1.4.1) gli autovalori e gli autovettori
associati alla matrice simmetrica Y;
• qr(Y): procede alla decomposizione di Y secondo l’algoritmo QR, cosı̀ come suggerito da Dongarra et al. (1978); la matrice dei coefficienti della decomposizione
ed altre informazioni quali il rango di Y, sono memorizzati sottoforma di “lista”
(cfr. 1.4.1);
• solve(Y): porge la matrice inversa di Y;
• solve(Y,x): risolve l’equazione indicata; la soluzione è, dunque, x Y −1 ;
• svd(Y): procede alla decomposizione di Y secondo l’algoritmo SVD, cosı̀ come
suggerito da Dongarra et al. (1978); i risultati sono presentati sottoforma di
“lista”. Per una semplice applicazione cfr. Esempio 1.6.7;
33
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
• t(Y): porge la trasposta di Y;
• outer(x,y,funzione): costrusice una nuova matrice i cui elementi risultano
essere [i,j]=funzione(x[i],y[i],...). Se la funzione che si desidera applicare è una funzione predefinita ( ad esempio +, *, /, , sum, ...) questa deve
obbligatoriamente essere racchiusa entro virgolette, mentre ciò non si applica se
è una funzione creata ad hoc dall’utente 8 . Per alcune semplici applicazioni, cfr.
Esempio 1.3.12 e 2.1.11.
1.4
Oggetti complessi
Come si disse, in R è possibile costruire oggetti a loro volte costituiti da altri oggetti
elementari, non necessariamente della stessa modalità.
Tali nuovi oggetti, che abbiamo definito complessi, sostanzialmente evitano il propagarsi di variabili (nomi, etichette, ...) e rendono quindi più chiara una sessione di
lavoro in R. A seconda della loro natura, si distinguono in “liste” e “data frame”.
1.4.1
Liste
Le “liste” vengono definite mediante l’istruzione:
nomelista<-list(label1=object1,label2=object2,...,labeln=objectn)
dove nomelista è il nome della “lista” che si intende creare e gli argomenti di list
sono oggetti elementari già esistenti a cui si attribuisce un’etichetta (label) che servirà successivamente a riconoscerli ed eventualmente estrarli ad uno ad uno. Ciò
avviene semplicemente digitando il nome della lista seguito da quello dell’oggetto che
si desidera estrarre, preceduto, questo dal prefisso $, ad esempio nomelista$label1.
I nomi che identificano gli elementi di una lista posono essere visualizzati in qualsiasi
momento ricorrendo al comando names(nomelista).
Esempio 1.4.1 Creazione, a partire degli oggetti x<-seq(1:10) e a<-letters[1:5], della
lista mia.lista .
Posto di attribuire all’oggetto elementare x l’etichetta dati e all’oggetto a l’etichetta stringa,
il problema viene risolto ricorrendo all’istruzione:
> mia.lista<-list(dati=x,stringa=a)
La visualizzazione del contenuto di una lista avviene impartendo il comando mia.lista, il
quale porge:
8
Si noti che il comando outer(x,y,*) può essere sosituito da x %o% y.
34
E. D. Isaia, Linguaggio R e applicazioni statistiche
$dati
[1] 1 2 3 4 5 6 7
$stringa
[1] "a" "b" "c" "d" "e"
8
9 10
In altri termini, la lista mia.lista contiene due diversi oggetti elementari, ciascuno dei quali
identificabile dalla rispettiva etichetta preceduta dal simbolo riservato $.
♥
Esempio 1.4.2 Visualizzazione degli elementi contenuti in mia.lista e successiva estrazione
dell’oggetto $dati. Sono suficienti i comandi:
> names(mia.lista)
[1] "dati"
"stringa"
> mia.lista$dati
[1] 1 2 3 4 5 6 7
8
9 10
È appena il caso di osservare che con nuova.x<-mia.lista$dati si crea un nuovo oggetto
che conterrà, appunto, gli elementi di $dati.
♥
Esempio 1.4.3 Si immagini che l’oggetto ms.AB, con struttura di matrice, rappresenti la
distribuzione congiunta dei caratteri colore degli occhi e colore dei capelli di 290 individui di
sesso maschile:
> ms.AB<-array(c(32,38,10,3,11,50,10,30,10,25,7,3,15,7,8,31),dim=c(4,4))
> ms.AB
[,1] [,2] [,3] [,4]
[1,]
32
11
10
15
[2,]
38
50
25
7
[3,]
10
10
7
8
[4,]
3
30
3
31
Desiderando attribuire alle modalità di ciascuna mutabile statistica (m.s.) le appropriate
etichette, possiamo ricorrere ai comandi dimnames() e list() nel modo seguente:
> dimnames(ms.AB)<-list(Capelli=c("Neri","Castani","Rossi","Biondi"),
Occhi = c("Neri","Castani","Verdi","Azzurri"))
ottenendo, coerentemente:
> ms.AB
Occhi
Capelli
Neri Castani Verdi Azzurri
Neri
32
11
10
15
Castani
38
50
25
7
Rossi
10
10
7
8
Biondi
3
30
3
31
35
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
♥
Osservazione 1.4.1 Molte procedure di analisi, oltre alla visualizzazione di un output standard, prevedono la creazione automatica di liste contenenti risultati intermedi
che possono essere riacquisiti per successive elaborazioni.
È buona norma, inoltre, documentare, in fase di programmazione, le eventuali liste
create come sottoprodotto dalle funzioni via, via implementate.
1.4.2
Data frame
Analogamente alle liste, i “data frame” vengono definiti mediante l’istruzione:
nomedf<-data.frame(label1=object1,label2=object2,...,labeln=objectn)
dove manifestamente nomedf è il nome del data frame che si intende creare metre gli
argomenti di data.frame sono oggetti elementari già esistenti e di egual cardinalità
a cui è possibile attribuire un’etichetta (label) che consente di riconoscerli in modo
più spedito. Benché i data frame cosı̀ creati abbiano struttura list, si differenziano
dalle “liste” per come vengono estratti e gestiti i singoli componenti.
Definito un data frame, affinché i suoi elementi siano disponibili 9 , occorre impartire
il comando attach(nomedf), in seguito al quale i singoli componenti si comportano
quali comuni variabili. Il comando detach(nomedf) scarica il data frame dall’area di
lavoro.
Ricordiamo, infine, che i nomi che identificano gli elementi di una data frame posono
essere visualizzati in qualsiasi istante ricorrendo al comando names(nomedf).
Esempio 1.4.4 Creazione del data frame mydata contenente, in forma compatta, due variabili di interesse per successive elaborazioni:
>
>
>
>
>
>
1
2
3
4
5
6
rm(list=ls())
sex<-c("M","M","M","F","M","F","M","M","F","M","F")
age<-c(21,23,24,21,23,24,25,26,24,25,21)
mydata<-data.frame(sesso=sex,eta=age)
rm(sex, age)
mydata
sesso eta
M 21
M 23
M 24
F 21
M 23
F 24
9
Alcune funzioni, quali ad esempio lm() e +aov(), fanno tuttavia eccezione.
36
E. D. Isaia, Linguaggio R e applicazioni statistiche
7
M 25
8
M 26
9
F 24
10
M 25
11
F 21
> ls()
[1] "mydata"
> names(mydata)
[1] "sesso" "eta"
> str(mydata)
‘data.frame’: 11 obs. of 2 variables:
$ sesso: Factor w/ 2 levels "F","M": 2 2 2 1 2 1 2 2 1 2 ...
$ eta : num 21 23 24 21 23 24 25 26 24 25 ...
> mode(mydata)
[1] "list"
Si noti che l’area di lavoro contiene il solo oggetto mydata, i cui componenti, peraltro, non
sono ancora disponibili, infatti:
> sesso
Error: Object "sesso" not found
> eta
Error: Object "eta" not found
Desiderando effettuare alcune elaborazioni sui dati contenuti negli oggetti del data frame, è
necessario, come già si disse, ricorrere al comando attach(mydata); nel caso proposto, ad
esempio:
> attach(mydata)
> cat("L’eta’ media e’:",round(sum(eta)/length(eta),2),"\n")
L’eta’ media e’: 23.36
> detach(mydata)
♥
1.5
Modalità e struttura di un’oggetto
La modalità di un oggetto, verificabile, come si è già detto, con il comando mode(),
può essere modificata, con le dovute cautele, ridefinendo l’oggetto tramite le istruzioni
as.numeric oppure as.character.
Qualora un’oggetto possedesse modalità numerica, il comando typeof(oggetto), o
equivalentemente storage.mode(oggetto), ci informa circa la rappresentazione interna degli elementi dell’oggetto indicato, che può presentarsi come integer, real,
double oppure complex, che potrebbe essere modificata con i comandi as.integer,
37
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
as.real, as.double oppure as.complex. Si noti che in tal modo oggetti con struttura
di vettore o di matrice possono essere ridefiniti quali oggetti elementari.
Esempio 1.5.1 Definiti gli oggetti:
>
>
>
>
x<-seq(1:5)
a<-letters[1:10]
y<-cbind(x)
Y<-matrix(log(c(1:5)),log10(c(1:5)),nrow=5,ncol=2)
si osservi il comportamento delle istruzioni:
verifica
mode(x)
mode(a)
mode(y)
mode(Y)
→
→
→
→
esito
"numeric"
"character"
"numeric"
"numeric"
verifica
storage.mode(x)
storage.mode(a)
storage.mode(y)
storage.mode(Y)
→
→
→
→
esito
"integer"
"character"
"integer"
"double"
ed ancora:
> as.character(x)
[1] "1" "2" "3" "4" "5"
> as.integer(as.character(x))
[1] 1 2 3 4 5
> round(as.real(Y),3)
[1] 0.000 0.693 1.099 1.386 1.609 0.000 0.693 1.099 1.386 1.609
> as.integer(Y)
[1] 0 0 1 1 1 0 0 1 1 1
♥
Quanto alla struttura di un oggetto, qusta può esssere verificata con le istruzioni
intuitive is.vector(), is.matrix(), is.list(), is.data.frame().
Esempio 1.5.2 Con riferimento agli oggetti di cui all’Esempio 1.5.1, abbiamo:
verifica
is.vector(x)
is.vector(y)
is.vector(Y)
→
→
→
esito
TRUE
FALSE
FALSE
verifica
is.matrix(x)
is.matrix(y)
is.matrix(Y)
→
→
→
esito
FALSE
TRUE
TRUE
In sostanza solo gli oggetti y e Y hanno struttura di matrice secondo l’accezione dell’algebra
lineare; in tale ambito il primo risulta essere un vettore (riga), il secondo una matrice.
♥
In linea di massima, la struttura di un oggetto può eventualmente essere modificata
ricorrendo ai comandi as.vector(), as.matrix(), as.data.frame(), tenendo conto
che:
38
E. D. Isaia, Linguaggio R e applicazioni statistiche
• as.matrix() applicato ad un oggetto elementare lo trasforma in un vettore
colonna; quindi il comando equivale a rbind();
• se un’elemento di un data frame è alfanumerico, la matrice che si genera con
as.matrix() avrà modalità alfanumerica;
• data una matrice di ordine n × p, con as.data.frame() si definisce un data
frame i cui elementi corrispondono alle p colonne della matrice specificata.
1.6
Funzioni definibili dall’utente
R consente all’utente una diretta programmazione di funzioni di qualsiasi natura; in
altri termini egli potrà, a seconda delle proprie esigenze, arricchire l’ambiente di lavoro
con specifiche funzioni.
Tra l’altro, quasi i tutti i comandi R che si utilizzano abitualmente sono funzioni
definite a partire da comandi elementari.
Prima di affrontare tale argomento, ci pare utile accennare alla possibilità di creare
cicli iterativi ricorrendo, a seconda delle esigenze, ai costrutti autoesplicativi:
• for (variabile in (range)) {istruzioni}
• while (condizione) {istruzioni}
• repeat (condizione) {istruzioni}
Cosı̀ il costrutto retto da for consente di ripetere le istruzioni contenute appunto in
{istruzioni} fintanto che la variabile specificata appartiene all’insieme numerico
definito in range.
Buona norma è comunque non fare ricorso a cicli iterativi quando esistono funzioni
interne che possono sopperire allo scopo che ci si prefigge.
Esempio 1.6.1 Creazione del vettore y che conterrà il quadrato dei primi dieci interi:
> (y<-integer(10))
[1] 0 0 0 0 0 0 0 0 0 0
> for(i in 1:10) {y[i]<-i^2}
> y
[1]
1
4
9 16 25 36
49
64
81 100
Ovviamente saremmo giunti allo stesso risultato in modo diretto impartendo le istruzioni:
> (y<-(c(1:10))^2)
[1]
1
4
9 16
25
36
49
64
81 100
39
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
♥
Esempio 1.6.2 Creazione , a partire dall’oggetto y<-c("R"), del vettore x che conterrà la
replicazione "R","R","R".
Ricorrendo ad un ciclo retto da for:
> y<-c("R")
> x<-for(i in 1:3){print(rep(y,i))}
[1] "R"
[1] "R" "R"
[1] "R" "R" "R"
> x
[1] "R" "R" "R"
In modo diretto, ricorrendo alla funzione rep:
> y<-c("R")
> (x<-rep(y,3))
[1] "R" "R" "R"
♥
Come un qualsiasi altro linguaggio di programmazione, R consente il ricorso a condizioni logiche mediante i costrutti:
• if (condizione){istruzioni}
• if (condizione){istruzioni} else {istruzioni}
• if (condizione){istruzioni} elseif {istruzioni}
tenendo a mente la tabella che segue:
simbolo
==
=>
&&
!
significato
equal to
greater or equal to
and
not
simbolo
!=
<=
||
significato
not equal to
less or equal to
or
Esempio 1.6.3 Si immagini che la rilevzione di un carattere quantitativo su un collettivo statistico abbia fornito in corrispondenza ad un (solo) individuo una mancata risposta (“missing
value”):
> x<-c(NA,20,21,20,23,27,25,27,25,23,20,21,27)
40
E. D. Isaia, Linguaggio R e applicazioni statistiche
Desiderando sostituire il valore mancante con la mediana delle osservazioni valide, possiamo
ricorrere all’istruzione:
> c(median(x[!is.na(x)]),x[!is.na(x)])
[1] 23 20 21 20 23 27 25 27 25 23 20 21 27
dove median(x[!is.na(x)]) calcola appunto la mediana degli elementi di x depurati dal
valore mancante.
♥
Ritornando al problema inizialmente postoci, la sintassi atta alla creazione di una
funzione è:
nome<-function(parametri){comandi}
dove il nome è a cura dell’utente, in parametri è acclusa l’eventuale lista di parametri (o meglio oggetti di natura qualsiasi) mentre in comandi sono annotate valide
istruzioni R.
Si noti che tutti gli oggetti definiti entro il corpo della funzione lo sono solo localmente;
al fine di definirli globalmente, con le dovute cautele, si può ricorrere, in fase di
definizione, all’assegnazione rafforzativa <<-. A tal proposito, tuttavia, è buona norma
offrire l’output sottoforma di lista o, eventualmente, di data frame.
È importante, poi, osservare che una funzione può contenere, al suo interno, altre
funzioni che, ovviamente, risulteranno definite solo localmente.
Nel seguito presentiamo, a puro scopo didattico, alcuni esempi di function.
Esempio 1.6.4 Creazione della funzione ipotenusa(a,b) che calcola la misura dell’ipotenusa di un triangolo rettangolo i cui cateti misurano a e b.
1
> ipotenusa<-function(a,b){sqrt(a^2+b^2)}
Il successivo comando ipotenusa(10,12) porge il risultato 15.6205.
Si osservi il comportamento delle istruzioni:
> ipotenusa(1,1)
[1] 1.414214
> ipotenusa(c(1:5),1)
[1] 1.414214 2.236068 3.162278 4.123106 5.099020
♥
Esempio 1.6.5 Creazione della funzione disp.nk che provvede al calcolo delle disposizioni
senza ripetizione nk ! = n (n − 1) · · · (n − k + 1). Sono sufficienti le istruzioni:
1
> disp.nk<-function(n,k){prod(n:(n-k+1))}
41
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Cosı̀, ad esempio:
> for (n in 1:4) print(disp.nk(n,n))
[1] 1
[1] 2
[1] 6
[1] 24
Alla luce di quanto
si è tentati di scrivere una semplice funzione per il calcolo dei coef, sopra,
ficienti binomiali nk , con k ≤ n; ciò può essere evitato ricorrendo al comando choose(n,k),
infatti, ad esempio:
> choose(10,c(0:10))
[1]
1 10 45 120 210 252 210 120
45
10
1
♥
Esempio 1.6.6 Creazione della funzione somma che, partendo da una matrice di input, provvede al calcolo della somma generale, nonché delle somme di riga e di colonna; i risutati
verranno inseriti nell’oggetto temporaneo con struttura di lista somma.out, che potrà essere
visualizzato o memorizzato a seconda delle esigenze dell’utente:
1
2
3
4
5
6
7
8
9
10
11
> somma<-function(X,print=TRUE,print.out=FALSE)
{
if(is.data.frame(X)) {X<-as.matrix(X)}
if (!is.matrix(X)) {stop("X deve essere una matrice")}
t.riga<-apply(X,1,sum)
t.col<-apply(X,2,sum)
t<-sum(X)
somma.out<-list(tot.riga=t.riga,tot.col=t.col,tot=t)
if(print==TRUE) {return(somma.out)}
if(print.out==TRUE) {somma.out<<-somma.out}
}
A commento:
— in riga [1] viene definita la funzione somma che ha quale unico input l’oggetto matrice
con struttura di matrice. Le due opzioni print=TRUE e print.out=FALSE fissano la
situazione di default: i risultati vengono visualizzati ma non memorizzati in un oggetto
in uscita dalla funzione;
— il corpo della funzione è racchiuso entro le righe [2] e [11];
— le righe [3] e [4] eseguono un controllo sull’oggetto X di input, il quale deve avere
struttura di matrice o di data frame; se tale condizione non è soddisfatta la funzione
visualizza un avviso di errore;
42
E. D. Isaia, Linguaggio R e applicazioni statistiche
— le righe [5], [6] e [7] provvedono ai calcoli richiesti ed in riga [8] viene definito l’oggetto
somma.out con struttura di lista contenente, appunto, i risultati;
— in riga [9] a seconda del valore TRUE o FALSE assunto dalla variabile flag print viene
visualizzata la lsita somma.out;
— in riga [10] a seconda del valore TRUE o FALSE assunto dalla variabile flag print.out
viene creata la lsita in uscita somma.out. Generalmente tali condizioni vengono scritte
in modo compatto: if(print) e if(print.out).
Cosı̀ con riferimento, ad esempio, alla matrice:
)
*
1 3
A=
2 4
avremo:
> A<-matrix(c(1:4),nrow=2,ncol=2)
> somma(A)
$tot.riga
[1] 4 6
$tot.col
[1] 3 7
$tot
[1] 10
> somma(A,print=FALSE,print.out=TRUE)
> somma.out
$tot.riga
[1] 4 6
$tot.col
[1] 3 7
$tot
[1] 10
♥
Esempio 1.6.7 Come già si disse, il calcolo del determinante di una matrice quadrata Y
può essere svolto tramite la funzione det() che, perlomeno nella situazione di default, ricorre
alla funzione qr(Y). Lo stesso risultato lo si può ottenere tramite la funzione svd(Y), la quale
(Dongarra et al. 1978) procede alla decomposizione di Y come:
Y = U D Vt
dove U e V sono matrici con colonne ortonormali di dimensione pari a ncol(Y) e ncol(Y)
rispettivamente, mentre D è una matrice diagonale contenente i valori singolari di Y. I risultati di interesse della decomposizione, proposti sottoforma di lista sono $d, vettore contenente
i valori singolari di Y, $u, matrice le cui colonne corrispondono agli autovettori sinistri di Y
e $v, matrice le cui colonne corrispondono agli autovettori destri di Y.
43
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Il valore assoluto del determinante di Y corrisponde dunque al prodotto degli elementi della
diagonale principale di D. Quanto al segno del determinante, esso sarà negativo se il numero
dei valori singolari di Y è pari, positivo altrimenti; tale condizione viene verificata tramite
length(diag(Y))%%2. Possiamo, quindi, scrivere la seguente funzione:
1
2
3
4
5
6
> det.new<-function(Y)
{
det<-prod(svd(Y)$d)
if (length(diag(Y))%%2 == 1) {-det}
else {det}
}
Cosı̀, ad esempio:
> (M<-matrix(c(1,1,0,1,1,1,0,1,1),nrow=3,ncol=3))
[,1] [,2] [,3]
[1,]
1
1
0
[2,]
1
1
1
[3,]
0
1
1
> det.new(M)
[1] -1
> det(M)
[1] -1
♥
1.7
Su alcune funzioni matematiche
Presentiamo alcune funzioni matematiche che possono tornare utili per la risoluzione
di specifici problemi e necessitano in input di oggetti di tipo expression o function.
In forma schematica, abbiamo:
• D(funzione,"variabile"): consente il calcolo simbolico della derivata prima
di una funzione, definita quale expression(), rispetto alla variabile di interesse,
che dovrà essere indicata sottoforma di stringa.
Esempio 1.7.1 Data la funzione f (x, y) = exp(−(x2 + y 2 )), ci proponiamo di:
— calcolare simbolicamente le derivate prime parziali:
> f<-expression(exp(-(x^2+y^2)))
> D(f,"x")
-exp(-(x^2 + y^2)) * (2 * x)
> D(f,"y")
-exp(-(x^2 + y^2)) * (2 * y)
44
E. D. Isaia, Linguaggio R e applicazioni statistiche
!!
!!
!!
— valutare il determinante (fxx fyy − fxy ) della matrice hessiana in corrispondenza al
punto di coordinate (x = 0, y = 0):
> x<-0
> y<-0
> eval(D(D(f,"x"),"x"))*eval(D(D(f,"y"),"y")) - 2*eval(D(D(f,"x"),"y"))
[1] 4
Per inciso:
> D(D(f,"x"),"x")
-exp(-(x^2 + y^2)) * 2 - exp(-(x^2 + y^2)) * (2 * x) * (2 * x)
> D(D(f,"y"),"y")
-exp(-(x^2 + y^2)) * 2 - exp(-(x^2 + y^2)) * (2 * y) * (2 * y)
> D(D(f,"x"),"y")
exp(-(x^2 + y^2)) * (2 * y) * (2 * x)
♥
• uniroot(function(x) espressione,interval=c(a,b),tol=1e-30): ricerca
gli eventuali zeri della funzione f (x) definita quale function, nell’intervallo
(a, b).
Esempio 1.7.2 A commento della funzione uniroot, proponiamo i seguenti problemi:
— data la funzione f (x) = x2 − 1, ricerchiamone gli zeri nell’intervallo (0, 2):
> str(uniroot(function(x) x^2-1,interval=c(0,2),tol=1e-30))
List of 4
$ root
: num 1
$ f.root
: num 0
$ iter
: int 8
$ estim.prec: num 6.51e-05
— data la funzione f (x) = (x − 1)2 (x + 1)2 , ricerchiamo gli zeri della sua derivata prima
nell’intervallo10 (−.5, .5). Il problema sarebbe di semplice soluzione se immettessimo
direttamente la derivata prima di f (x); qui, tuttavia, preferiamo calcolare (simboli!
camente) fx e passarne l’espressione alla funzione uniroot. A tal fine sfruttiamo le
istruzioni:
> f<-expression((x-1)^2 * (x+1)^2)
> dfdx<-as.function(list(x="x",D(f,"x")))
> uniroot(dfdx,low=-.5,up=.5)$root
[1] 0
1
2
3
4
!
10
In effetti, come si può facilmente verificare algebricamente, fx si annulla in corrispondenza a tre
distinti punti in (−2, 2).
45
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
A commento è bene notare che, definita f (x) quale expression ai fini della derivazione,
!
in riga [2] trasformiamo l’espressione ottenuta per fx in function, con argomento x, :
cioè:
> dfdx
function (x = "x")
2 * (x - 1) * (x + 1)^2 + (x - 1)^2 * (2 * (x + 1))
quindi passiamo l’oggetto dfdx alla funzione uniroot.
— data la funzione f (x) = exp(−x), ricerchiamo il più piccolo valore di x per cui f (x)
può considerarsi “numericamente nulla”, cioè, ad esempio, se f (x) = 10 −300 . A tal fine
è sufficiente l’istruzione:
> str(uniroot(function(x) exp(-x)-10^(-300),interval=c(0,1000),
tol=1e-30))
List of 4
$ root
: num 691
$ f.root
: num 2.37e-314
$ iter
: int 21
$ estim.prec: num 3.41e-13
♥
• optimize(function(x) espressione,interval=c(a,b),maximum=FALSE): ricerca un eventuale punto di minimo (o di massimo, ponendo maximum=TRUE)
della funzione f (x) definita quale function, nell’intervallo (a, b).
Esempio 1.7.3 Data la funzione f (x) = sin(x), ci proponiamo di calcolarne il minimo ed il
massimo nell’intervallo (0, 2 π). A tal fine sopperiscono le istruzioni:
> optimize(function(x) sin(x),interval=c(0,2*pi),tol=1e-30,maximum=FALSE)
$minimum
[1] 4.712389
$objective
[1] -1
> optimize(function(x) sin(x),interval=c(0,2*pi),tol=1e-30,maximum=TRUE)
$maximum
[1] 1.570796
$objective
[1] 1
Si noti che, data ad esempio la funzione f (x) = x3 , la ricerca di un punti di minimo (!) in
(−2, 2) mediante optimize porgerebbe:
46
E. D. Isaia, Linguaggio R e applicazioni statistiche
> optimize(function(x) x^3,interval=c(-2,2),tol=1e-30,maximum=FALSE)
$minimum
[1] -2
$objective
[1] -8
risultato evidentemente privo di senso.
♥
• integrate(funzione,lower=, upper=,subdivisions=100): consente il calcolo, per quadratura numerica, dell’integrale della funzione f (x) definita quale
function nell’intervallo (a, b), finito o infinito.
2
Esempio 1.7.4 Data la funzione integranda f (x) = √1 exp(− x2 ):
2π
> f<-function(x) (2*pi)^(-.5)*exp(-.5*x^2)
ci proponiamo di:
— calcolare il suo integrale nell’intervallo (−3, 3):
> str(integrate(f,lower=-3,upper=3))
List of 5
$ value
: num 0.997
$ abs.error
: num 9.25e-07
$ subdivisions: int 1
$ message
: chr "OK"
$ call
: language integrate(f = f, lower = -3, upper = 3)
- attr(*, "class")= chr "integrate"
.3
.3
Ovviamente, per la simmetria di f (x), risulta −3 f (x) dx = 2 0 f (x) dx; numericamente, infatti:
***
— calcolare il suo integrale nell’intervallo (−∞, t), con t = −3, −2.5, . . . , 0; ricorrendo ad
un semplice ciclo retto da for, abbiamo:
> for(b in seq(-3,0,by=.5)){
cat(integrate(f, lower = -Inf, upper = b)$value,"\n")}
0.001349899
0.006209665
0.02275013
0.0668072
0.1586553
0.3085375
0.5
♥
47
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
1.8
Lettura e registrazione di archivi
In R vi sono sostanzialmente due modi per leggere e/o registrare archivi di dati e
questi si basano sui comandi scan() - write() e read.table() - write.table()
rispettivamente. A questi è giocoforza affiancare il particolare comando data() che
permette di acquisire dati registrati in formato particolare che abitualmente fanno
parte integrante dei “package” di base o aggiuntivi di R.
Ricordiamo che comunque è possibile importare e/o esportare dati in formati riconoscibili da altri pacchetti, ad esempio Excell, Oracle, SAS, Spss, ...; a tal fine, tuttavia,
occorre disporre di “funzioni” o “package” ad hoc, facilmente reperibili consultando
il sito http://www.r-project.org.
1.8.1
I comandi scan() e write()
Lettura di un file di dati con struttura “blank or tab delimited” può avvenire riccorrendo al comando scan() la cui sintassi è:
nomelista<-scan("filename",list(label1=type,...,labeln=type))
dove filename è l’archivio dati di interesse, label sono le etichette attribuite a ciascun
oggetto definito implicitamente per ciascuna colonna del file in lettura, mentre type
indica la modalità dei singoli oggetti che verranno inclusi nella lista (type=0 e type=""
per oggetti con modalità numerica o alfanumerica rispettivamente). Si osservi che
l’oggetto nomelista ha struttura list.
Esempio 1.8.1 La lettura del file di dati Mydata.dat con struttura “blank or tab delimited”
170 77 M
182 81 M
172 55 F
........
176 67 F
avverrà previa definizione della lista mieidati ed estraendo da essa i singoli oggetti di
interesse. In pratica:
>
>
>
>
mieidati<-scan("Mydata.dat",list(x=0,y=0,sex=""))
altezza<-mieidati$x
peso<-mieidati$y
sesso<-mieidati$sex
Una forma alternativa, meno elegante, ma forse più chiara, potrebbe essere la creazione di una
lista priva di etichette e l’attribuzione delle stesse in seconda battuta; ad esempio la lettura
del file Mydata.dat potrebbe avvenire in accordo alle istruzioni:
48
E. D. Isaia, Linguaggio R e applicazioni statistiche
>
>
>
>
mieidati<-scan("Mydata.dat",list(0,0""))
x<-mieidati[[1]]
y<-mieidati[[2]]
sex<-mieidati[[3]]
♥
La scrittura, o registrazione, su file in formato “blank delimited” delle variabili di
interesse avviene con il semplice comando:
write(oggetto1,oggetto2,...,oggetton,file="filename")
Esempio 1.8.2 La scrittura sul file Mydata.dat degli oggeti x, y e w avviene con il comando
> write(x,y,w,file="Mydata.dat")
♥
1.8.2
I comandi read.table() e write.table()
Mediante il comando read.table() è possibile acquisire in memeoria, sottoforma di
data frame, i dati contenuti in archivi con struttura “tab delimited”. La sintassi
minima del comando è:
nomedf<-read.table("filename",header = FALSE)
Gli oggetti, con struttura factors, del data frame acquisito in memoria vengono
indicati per default in V1,V2,V3,...
Qualora la prima riga dell’archivio contenesse il nome delle variabili, una corretta
lettura si avrebbe ponendo header = TRUE e gli oggetti del data frame assumerebbero
tali nomi.
Esempio 1.8.3 La lettura del file di dati Mydata.tab con struttura “tab delimited”:
altezza
170
182
172
...
176
peso
77
81
55
...
67
sesso
M
M
F
...
F
avviene tramite il semplice comando:
49
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> mieidati<-read.table(file="Mydata.tab",header=TRUE)
> mieidati
altezza peso sesso
1
170
77
M
2
182
81
M
3
172
55
F
4
176
67
F
5
170
77
M
6
182
81
M
7
170
77
M
8
171
65
F
9
170
77
M
10
165
55
F
11
180
77
M
12
172
81
M
13
160
77
M
14
192
81
M
15
170
77
M
16
172
67
F
A questo punto con attach(mieidati) si rendono disponibili i tre oggetti altezza, peso e
sesso per succcessive elaborazioni.
♥
In modo del tutto naturale, la scrittura su file di un generico data frame avviene con
il comando write.table(dataframe,file="filename").
1.8.3
Il comando data()
Sfruttando tale comando è possibile accedere in modo diretto agli archivi di dati
registrati direttamente sottoforma di lista o di data frame che, quale parte integrante
dei “package” di base o aggiuntivi di R, sono abitualmente posti nelle corrispondenti
directory \library\<package>\data.
A tal proposito, alcuni comandi utili sono:
• data(package=<package>): visualizza l’elenco ed eventualmente una breve descrizione degli archivi disponibili per il “package” specificato. Con data() si ottiene l’elenco del (o dei) “package” attualmente in uso, ad esempio base, ctest,
modreg ..., mentre con data(package=.packages(all.available=TRUE)) si ha
l’elenco completo degli archivi di dati relativi a tutti i “package” presenti nella
directory \library di R.
• help(package=<package>,<nome del file>): fornisce, se previsto, una breve
descrizione dell’archivio di dati specificato;
50
E. D. Isaia, Linguaggio R e applicazioni statistiche
• data(package=<package>,<nome del file>): carica in memoria l’archivio di
dati specificato.
Naturalmente l’utente può creare *** non so dove inserirlo *** qui o, penso meglio,
in un capitolo/paragrafo ad hoc sulle librerie.
1.9
Personalizzazione dell’ambiente di lavoro
L’ambiente di lavoro può essere personalizzato, a seconda delle esigenze dell’utente,
semplicemente modificando i valori di default delle diverse opzioni che definiscono ad
esempio il “prompt”, il numero di decimali visualizzati, la dimensione ed il layout
della pagina in fase di stampa e molte cose ancora.
Le modifiche, in linea di massima, possono essere attuate seguendo diverse vie, e più
precisamente:
— nel corso di una sessione di lavoro. In tal caso esse avranno unicamente valore
temporaneo a meno che non si salvi l’ambiente stesso, creando cosı̀ il file Rdata;
lanciando successivamente R tramite questo, si ritroveranno modificate;
— direttamente sul file Rprofile, sı̀ che esse divengono, per cosı̀ dire, permanenti;
Senza entrare in dettagli, la creazione del file Rdata ci pare la soluzione migliore,
anche perché in tal modo, lasciando integro il file Rprofile, si possono creare diverse
configurazioni di R poste, ad esempio, in altrettante directory di lavoro.
Desiderando ottenere l’elenco completo dei nomi delle opzioni su cui è possibile
intervenire, è sufficiente digitare names(.Options), infatti:
> names(.Options)
[1] "prompt"
[4] "expressions"
[7] "contrasts"
[10] "check.bounds"
[13] "error.messages"
[16] "show.signif.stars"
[19] "help.try.all.packages"
[22] "download.info"
[25] "device"
[28] "mailer"
"continue"
"width"
"echo"
"keep.source"
"ts.eps"
"show.coef.Pvalues"
"CRAN"
"encoding"
"pager"
"editor"
"digits"
"verbose"
"keep.source.pkgs"
"na.action"
"warn"
"timeout"
"papersize"
"unzip"
Per visualizzare i valori di default di ciascun parametro occorre digitare options()
oppure str(options()); quest’ultimo porge 11 :
11
Ovviamente a seconda della piattaforma su cui è installato R.
51
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> str(options())
List of 28
$ prompt
: chr "> "
$ continue
: chr "+ "
$ editor
: chr "Nedit"
$ expressions
: int 500
$ width
: int 79
$ digits
: int 7
$ contrasts
: Named chr [1:2] "contr.treatment"
"contr.poly"..- attr(*, "names")= chr [1:2] "unordered" "ordered"
$ echo
: logi TRUE
$ verbose
: logi FALSE
$ check.bounds
: logi FALSE
$ keep.source
: logi TRUE
$ keep.source.pkgs
: logi FALSE
$ error.messages
: logi TRUE
$ ts.eps
: num 1e-05
$ na.action
: chr "na.omit"
$ show.signif.stars
: logi TRUE
$ show.coef.Pvalues
: logi TRUE
$ warn
: num 0
$ help.try.all.packages: logi FALSE
$ CRAN
: chr "http://cran.r-project.org"
$ timeout
: num 60
$ download.info
: num 2
$ encoding
: int [1:256] 0 1 2 3 4 5 6 7 8 9 ...
$ papersize
: chr "a4"
$ device
: chr "X11"
$ pager
: chr "nedit"
$ unzip
: chr "tar"
Prima di procedere a modifiche dei parametri di default conviene creare una copia
degli stessi sı̀ da poter ripristinare in qualsiasi istante la situazione di default; ciò può
avvenire, ad esempio, impartendo le istruzioni:
>
>
>
>
default.opt<-options()
... modifiche dei parametri ...
... elaborazioni ...
options(default.opt)
52
E. D. Isaia, Linguaggio R e applicazioni statistiche
Le modifiche dei parametri avvengono con il comando options(opzione=valore);
ad esempio12 :
> default.opt<-options()
> pi
[1] 3.141593
> options(digits=20)
> pi
[1] 3.141592653589793
> options(prompt="@->")
@-> options(digits=2)
@-> pi
[1] 3.1
@-> options(default.opt)
> pi
[1] 3.141593
1.10
Le librerie e loro gestione
Come si è detto, a seconda delle esigenze dell’utente,può a volte capitare di dover disporre di particolari librerie matematiche, statistiche e/o grafiche aggiuntive, reperibili
al sito ufficiale http://www.r-project.org oppure costruite ad hoc.
Comunque sia, per un corretto funzionamento, i “package” dovranno essere posti nella
directory \library, la quale potrebbe assumere la seguente struttura:
\library
!→
!→
!→
...
!→
...
!→
\base
\ctest
\modreg
...
\personale
...
\ts
Ciò premesso, l’elenco che segue riporta in modo schematico alcuni comandi atti alla
gestione dei diversi “package” presenti \library:
• (.packages()): indica quali “package” sono attualmente in uso. Abitualmente,
la configurazione di Rprofile prevede il caricamento della sola libreria \base;
infatti:
12
Si ricordi che nel numero di decimali da visualizzare è compreso il separatore.
53
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> (.packages())
[1] "base"
• .packages(all=TRUE): fornisce la lista dei “package” disponibili in \library.
Nel caso dello scrivente:
> .packages(all=TRUE)
[1] "KernSmooth"
"MASS"
[5] "bootstrap"
"class"
[9] "eda"
"foreign"
[13] "modreg"
"mva"
[17] "nnet"
"rnotes"
[21] "spatial"
"splines"
[25] "ts"
"xtable"
"base"
"cluster"
"integrate"
"nlme"
"rpart"
"stepfun"
"boot"
"ctest"
"lqs"
"nls"
"scatterplot3d"
"survival"
dove rnotes è una libreria creata ad hoc e contenente la maggior parte delle
funzioni introdotte nel corso del presente lavoro.
• library(): visualizza, in una finestra ad hoc, l’elenco di tutti i “package”
disponibili con, a fianco, una breve descrizione degli stessi;
• library(help=<package>): porge, in una finestra apposita, un breve resoconto
circa il “package” specificato;
• library(<package>): carica in memoria il “package” indicato. Cosı̀, ad esempio, desideando disporre delle funzioni definite in rnotes sarà sufficiente il
comando:
> library(rnotes)
Library ‘rnotes’; Copyright (C) 2001 E.D.Isaia
type ‘help(package=rnotes)’ for summary information
> (.packages())
[1] "rnotes" "base"
• detach(package:<package>): scarica dalla memoria il “package” specificato.
Ad esempio:
> detach(package:rnotes)
> (.packages())
[1] "base"
54
Capitolo 2
Cenni sulle procedure grafiche
Dedichiamo, ora, la nostra attenzione alla descrizione, seppur sommaria, delle principali funzioni che consentono, a partire da oggetti definiti, la creazione di grafici
“standard”, precisando sin da ora che l’utente può ridefinire tali funzioni o crearne
nuove secondo le proprie necessità.
È bene suddividere, perlomeno idealmente, le funzioni grafiche nelle seguenti due
categorie:
— funzioni grafiche di “primo livello”: generano il grafico specificato corredato di
assi, etichette, legende, titoli. Tali funzioni, è bene ricordalo, reinizializzano la
finestra grafica;
— funzioni grafiche di “secondo livello”: consentono di sovraimporre al grafico
corrente alcune informazioni aggiuntive, quali, nuovi punti, linee, commenti od
altro.
In R, inoltre, è possibile intervenire in modo diretto sui parametri di default dell’ambiente grafico, modificandone a piacere l’aspetto.
2.1
Funzioni grafiche di “primo livello”
Si tratta essenzialmente di una serie di funzioni predefinite che consentono la realizzazione di grafici “standard”. Tra esse val qui la pena citare le seguenti:
2.1.1
Funzione plot(x,y)
Si tratta di una funzione assai generica e il risultato è condizionato dalla modalità del
primo oggetto posto quale argomento.
Infatti:
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
— se x e y sono oggetti o vettori numerici, plot(x,y) porge il “classico” diagramma
a dispersione di y in funzione di x. Allo stesso risultato si perviene con plot(z),
posto z sia una matrice (nx2) ad elementi numerici oppure una lista;
— se y rappresenta una serie storica, con plot(y) viene rappresentata la serie
stessa, con in ascissa i valori dell’indice di y, cioè c(1:lenght(n)), salvo altra
specificazione.
— qualora x e y siano due oggetti con modalità factor il primo e numerica il
secondo, plot(x,y) produce un diagramma a dispersione di y per ciascun livello
di x.
— se y è un vettore con modalità complessa, plot(y) produce un diagramma a
dispersione con in ordinata la parte immaginaria degli elementi di y ed in ascissa
quella reale.
Tali sono gli argomenti obbligatori della funzione plot(). Il grafico offerto, con le
avvertenze di cui sopra, provvede in modo automatico (situazione di default 1 .) alla
rappresentazione dei punti di coordinate (x, y) mediante il simbolo ◦, alla suddivisione
degli assi x e y in intervalli uguali tra il massimo ed il minino dei valori osservati,
nonché alla visualizzazione delle etichette per gli assi x e y e di un titolo che nella
forma standard è del tipo ‘Plot of ...”.
Tale situazione di default può essere modificata dall’utente ricorrendo ad un ventaglio
piuttosto esteso di opzioni; tra queste val la pena menzionare:
— opzione che modifica la presentazione degli assi cartesiani:
frame.plot=TRUE
frame.plot=FALSE
grafico racchiuso in una scatola (default);
visualizzati i soli assi delle ascisse e delle ordinate
— opzioni che alterano il campo di escursione degli assi x e/o y:
xlim(c(min,max))
ylim(c(min,max));
— opzioni che modificano il tipo di rappresentazione dei punti di coordinate (x, y).
Per default essi vengono rappresentati mediante un punto (◦); tale situazione
può essere modificata ricorrendo a diverse opzioni; tra esse menzioninamo le
seguenti:
1
Salvo diversa configurazione dei prametri grafici; a tal proposito cfr. paragrafo 2.3
56
E. D. Isaia, Linguaggio R e applicazioni statistiche
type="l"
type="b"
type="s"
type="h"
type="n"
coppie (x, y) congiunte da una linea;
coppie (x, y) congiunte da una spezzata;
coppie (x, y) congiunte da una spezzata a gradini;
congiunge con un segmento x con il corrispondente y;
coppie (x, y) non rappresentate;
— opzioni che modificano la natura degli assi x e/o y:
log="x"
log="y"
log="xy"
dati in ascissa in forma logaritmica;
dati in ordinata in forma logaritmica;
entrambi gli assi in forma logaritmica;
— opzioni, valide per tutte le procedure grafiche, che permettono di modificare
titoli ed etichette:
main="stringa"
xlab="stringa"
ylab="stringa"
il titolo presenta l’espressione in striga;
l’asse x etichettato con l’espressione in striga;
l’asse y etichettato con l’espressione in striga.
Evidentemente tutte le etichette scompaiono con le opzioni main="", xlab=""
e ylab="". A volte può essere utile sopprimere del tutto, con il comando
ann=FALSE, le annotazioni ed inserirle successivamente a piacere tramite il comando title (cfr. paragrafo 2.2).
2.1.2
Funzione matplot(x,y)
Tale funzione, del tutto identica a plot per quanto concerne le diverse opzioni, se ne
differenzia poiché permette di rappresentare più curve su uno stesso grafico.
2.1.3
Funzione hist(x)
Tale funzione consente la creazione di un istogramma dell’oggetto numerico indicato
quale argomento.
Nella situazione di default il numero delle classi dell’istogramma è calcolato suddividendo il campo di escursione di x in n intervalli di ugual ampiezza, avendo cura
di porre n = {1 + log 2 [length (x)]}. Infatti la funzione plot() contiene l’istruzione
pretty(range(x),1+log2(length(x))).
Tale situazione può essere modificata a piacere dall’utente ricorrendo all’opzione
breaks=n, con n intero positivo. Ricorrendo a tale opzione, in R è possibile creare istogrammi di frequenze per dati raccolti in classi di modulo non costante; a tal
proposito, posto che x contenga 100 osservazioni comprese tra 10.5 e 29.7, l’istruzione:
> hist(x,breaks=c(10,15,20,30))
57
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
porge un istogramma con classi (10 - 15], (15 - 20] e (20 - 30] ed in ordinata le
corrispondenti densità, ovvero i rapporti tra le frequenze assolute di classe ed il modulo
della classe stessa. Una semplice applicazione è riportata all’Esempio ??.
Sempre per default, in ordinata vengono riportate, per ciascuna classe, le frequenze assolute; l’opzione freq=FALSE consente di riportare sull’asse delle ordinate le frequenze
relative2 .
Osserviamo, ancora, che il comando hist(...,plot=FALSE) non visualizza alcun
istogramma ma crea una lista contenene i seguenti oggetti:
$breaks
$density
$counts
$mids
$intensities
$xname
il cui significato è intuitivo. Per inciso, tale comportamento è proprio delle principali
funzioni grafiche, tranne plot().
2.1.4
Funzione boxplot(x,y,z,...)
Tale funzione consente di creare un diagramma a “scatola e baffi” degli oggetti numerici indicati quale argomento. Questi potrebbero alternativamnte corrispondere
ai diversi elementi di una lista o di un “data.frame”, a patto, in quest’ultimo caso,
che essi abbiamo tutti la medesima cardinalità. A tal proposito, si immagini che gli
oggetti mate e stat contengano, rispettivamente, i voti di Matematica e di Statistica
ottenuti da 10 studenti di un corso universitario:
> mate<-c(23,24,23,18,25,27,30,27,23,29)
> stat<-c(24,27,21,20,27,20,30,25,18,30)
Ai fini della costruzione dei diagrammi a “scatola e baffi” di cisacuna variabile si
possono impartire i seguenti comandi del tutto equivalenti nel risultato:
>
>
>
>
boxplot(mate,stat)
boxplot(list(mate,stat))
boxplot(data.frame(mate,stat))
boxplot(data.frame(cbind(mate,stat)))
Osserviamo, che in alcune situazioni può accadere di avere a disposizione due oggetti
elementari, il primo dei quali contenente le osservazioni individuali di una variabile di
interesse, il secondo le corrispondenti modalità di un certo fattore di stratificazione; in
tali siuazioni, senza dovere modificare la struttura dei dati, si può ricorrere, in fase di
definizione, all’espressione x~g, che indica che le osservazioni individuali contenute in
x debbono essere stratificate in funzione delle modalità di g. Riprendendo l’esempio
precedente, potremmo impartire i comandi:
2
Un’alternativa è rappresentata dall’opzione probability=TRUE.
58
E. D. Isaia, Linguaggio R e applicazioni statistiche
> voti<-c(mate,stat)
> materia<-c(rep(1,10),rep(2,10))
> boxplot(voti~materia)
Tra le numerose sono le opzioni, ci limitamo alle seguenti di carattere assai generale:
— range=n: consente di modificare la lunghezza dei “baffi”, che per default hanno
una lughezza pari a 1.5 volte la differenza interquartile 3 . Ponendo range=0 essi
si dimensionano in modo da includere i valori estremi;
— border=colori: colora i bordi del diagramma in accordo a quanto specificato
nel vettore colori;
— col=colore: la scatola viene riempita con il colore indicato;
— horizontal=FALSE: rappresenta la situazione di default; con horizontal=TRUE
i diagrammi vengono ruotati di 90 gradi.
2.1.5
Funzioni qqplot(x,y) e qqnorm(x)
Il ricorso a qqplot(x,y) consente di ottenere il diagramma a dispersione dei quantili
della variabile x rispetto a quelli della variabile y, con, ovviamente, length(x) non
necessariamente uguale a length(y).
Se si ha cura di porre y<-qnorm(ppoints(length(x)),mean(x),sd(x)), allora i
quantili di x sono raffrontati con quelli di una N (µ X , σX ). Un’alternativa consiste nel
ricorso al comando qqnorm(x), il quale porge il diagramma a dispersione dei quantili
della variabile x rispetto a quelli di una distribuzione normale standardizzata.
Le opzioni di tali funzioni sono del tutto analoghe a quelle presentate a proposito di
plot(x,y). Per una semplice applicazione, cfr. Esempio 4.2.3.
2.1.6
Funzione barplot(x) e piechart(x)
Tali funzioni permettono la creazione di semplici diagrammi a barre e a torta rispettivamente.
Il loro output grafico può essere arricchito, ad esempio,attribuendo delle etichette a
ciascun elemento dell’oggetto specficato quale argomento.
2.1.7
Funzione polygon(x,y)
Tramite tale funzione è possibile visualizzare poligoni i cui vertici sono contenuti negli
oggetti x e y. A titolo di esempio:
3
In altri termini,lasciano alla loro sinistra e destra circa il 5% delle osservazioni.
59
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
>
>
>
>
x<-c(9.154932,11.374214,9.313423,11.044401,8.634460,11.176227)
y<-c(12.66062,31.05207,17.42724,15.11586,22.99784,18.09190)
plot(x,y, type="n", xlab="", ylab="")
polygon(x,y,col="red")
2.1.8
Funzione curve(espressione)
Il ricorso a tale funzione consente di rappresentare graficamente sul piano cartesiano
di riferimento (x, y) una qualsiasi funzione indicata in espressione, scritta quale
funzione in x. La sintassi completa, peraltro di facile interpretazione è:
curve(espressione,from,to,n = 101,add=FALSE)
Ponendo add=TRUE è possibile sovraimporre una seconda curva al grafico corrente.
Un esempio di comando valido è, pertanto, curve(x^2*(1-x^2)), che potrebbe essere
migliorato definendo un intervallo in ascissa entro cui visualizzare la funzione stessa,
ad esempio porre curve(x^2*(1-x^2),-1,1). In alternativa avremmo potuto definire
la funzione f e successivamente rappresentarla graficamente con i comandi:
> f<-function(x) (x^2*(1-x^2))
> curve(f,-1,1)
2.1.9
Funzione grid(nx,ny)
Tale funzione consente di aggiungere ad un grafico una “griglia” composta da nx×ny
celle delimitate da altrettante linee tratteggiate. La situazione di default, ottenibile
con grid(), prevede un numero di celle pari al numero di “tick marks” presenti su
entrambi gli assi.
2.1.10
La funzione rect(xmin,xmax,ymin,ymax)
Ricorrendo a tale funzione possiamo costruire e visualizzare rettangoli con vertici i
punti di coordinate (xmin , ymin ) e (xmax , ymax ) definite dall’utente.
Quale esempio, suggeriamo all’utente di osservare il comportamento delle istruzioni:
> plot(c(0, 22), c(0, 22), type = "n")
> k<-4*(0:5)
> rect(0+k, 0+k, 2+k, 2+k)
Per inciso, è la funzione primitiva per la costruzione di istrogrammi.
60
E. D. Isaia, Linguaggio R e applicazioni statistiche
2.1.11
Funzione persp(x,y,z)
Tramite tale funzione possiamo rappresentare graficamente nello spazio cartesiano
(x, y, z) una qualsiasi funzione z = f (x, y) che verrà passata quale argomento. Argomenti obbligatori di persp sono:
— i vettori x e y contenentI i punti (x, y) in corrispondenza ai quali calcolare i
valori di z = f (x, y);
— la matrice quadrata z, di dimensione length(x)×length(y), contenente appunto i valori di z = f (x, y).
Desiderando, ad esempio, rappresentare graficamente la funzione:
x2 y 2
z=/
(x2 + y 2 )
per x ∈ (−10, 10) e y ∈ (−10, 10), saranno sufficienti le istruzioni:
1
2
3
4
5
>
>
>
>
>
x<-seq(-10, 10, length=50)
y<-x
f<-function(x,y){fz<-x^2*y^2/sqrt(x^2+y^2)}
z<-outer(x,y,f)
persp(x,y,z,theta=35,phi=35,col="lightgreen")
A commento:
— in riga [1] e [2] si definiscono gli intervalli per x e y entro cui visualizzare la
funzione z;
— la riga [3] definisce in modo chiaro la funzione f (x, y) di interesse;
— in riga [4], per ogni coppia (x, y), calcoliamo i valori della funzione f che risulteranno inseriti, tramite il comando outer(x,y,f), nella matrice z di ordine
dim(z)=length(x)×length(x), ovvero 50 × 50;
— in riga [5] il comando persp(...) visualizza il grafico richiesto.
Se osserviamo che la sintassi completa del comando è:
persp(x=seq(0,1,len=nrow(z)),y=seq(0,1,len=ncol(z)),z,
xlim=range(x),ylim=range(y),zlim=range(z,na.rm=TRUE),
xlab=NULL,ylab=NULL,zlab=NULL,main=NULL,sub=NULL,
theta=0,phi=15,r=sqrt(3),d=1,scale=TRUE,expand=1,
col=NULL,border=NULL,ltheta=-135,lphi=0,shade=NA,
box=TRUE,axes=TRUE,nticks=5,ticktype="simple",...)
61
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
la sintassi minima sarà dunque persp(z). Per ulteriori applicazioni, cfr. Esempi ??
e **.
2.1.12
Funzione pairs(x)
Ricorrendo a tale funzione è possibile, partendo da una matrice x contenente poniamo
s ≥ 2 colonne che rappresentano altrettante variabili di interesse, creare i diagrammi
a dispersione tra tutte le (s2 − s) combinazioni delle variabili oggetto di studio. La
sintassi per accedere a tale funzione è, nella sua veste più dimessa, pairs(x).
Tra le diverse opzioni, vale la pena menzionare:
— panel=function(x,y,...): consente di sovraimprimere ai diagrammi a dispersione una particolare funzione grafica definita dall’utente, ad esempio la
seguente, che sovraimpone a ciascun diagramma a dispersione la corrispondente
retta di regressione:
panel.fit<-function(x,y,col=par("col"),pch=par("pch"),cex=1)
{
points(x,y,pch=pch,col=col,cex=cex)
lines(x,lm(y~x)$coef[1]+lm(y~x)$coef[2]*x,col="red")
}
che può essere attivata con il comando pairs(x,panel=panel.fit). Lasciamo
al Lettore il commento della funzione proposta alla luce di quanto esposto ai
paragrafi 2.2 e 2.3 e 6.2.1.
Una funzione predefinita in R è panel.smooth, la quale aggiunge, a ciascun
grafico, una particolare curva di regressione cosı̀ come proposto da Cleveland
(1981);
— diag.panel=function(x,y,...): permette di inserire sulla diagonale principale della “matrice dei diagrammi a dispersione”, in luogo dei nomi delle s
variabili coinvolte (situazione di default), particolari funzioni grafiche a seconda delle esigenze dell’utente. A tal proposito, pensando di rappresentare le s
distribuzioni marginali mediante semplici istogrammi di frequenze, potremmo
definire la seguente funzione4 :
>panel.hist<-function(x, ...)
{
4
Per ragioni di comodo, le altezze degli istogrammi corrispondono alle frequenze assolute divise
per il massimo di esse.
62
E. D. Isaia, Linguaggio R e applicazioni statistiche
usr<-par("usr")
par(usr=c(usr[1:2],0,1.5) )
istogramma<-hist(x,plot=FALSE)
tagli<-istogramma$breaks
ntagli<-length(tagli)
y<-istogramma$counts/max(istogramma$counts)
rect(tagli[-ntagli],0,tagli[-1],y,col="lightblue")
par(usr=c(0,1,0,1))
}
che può essere attivata con il comando pairs(x,diag.panel=panel.hist). Lasciamo al Lettore il commento della funzione proposta, e ciò alla luce di quanto
esposto ai paragrafi 2.2 e 2.3. Per una semplice applicazione, cfr. Esempio 3.2.6.
— lower.panel=function(x,y,...) e upper.panel=function(x,y,...): consentono di inserire nelle celle, rispettivamente, a sinistra e a destra della diagonale principale della matrice dei diagrammi a disersione, particolari funzionidefinite dall’utente. Per un’applicazione, cfr. Esempio 3.2.6.
2.1.13
Altre funzioni grafiche
Oltre a quelle citate, in R sono implementate diverse altre funzioni grafiche utili
qualora si affronti lo studio di particolari problemi. Senza entrare in dettaglio, ci
limitano a fornirne un mero elenco, invitando il Lettore a consultare l’aiuto in linea
o il manuale di riferimento R Core Team (2000):
contour(x,y,z)
image(x,y,z)
2.2
coplot(...)
stripplot(x)
dotplot(x)
sunflowerplot(x,y)
Funzioni grafiche di “secondo livello”
A volte i grafici ottenuti in modo automatico mediante le funzioni di “primo livello” non corrispondono a quanto desiderato, nel senso che possono mancare dettagli,
informazioni aggiuntive, ...
Le funzioni di “secondo livello” possono esserci di aiuto, dal momento che esse vengono
semplicemente sovraimposte all’output grafico corrente. Di esse ci limitamo a citare
le seguenti:
• abline(a,b): aggiunge un segmento di retta di equazione y = a + bx al grafico
corrente;
63
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
• abline(h=y), abline(v=x): permettono di aggiungere un segmento di retta orrizontale e verticale rispettivamente a partire dalle coordinate y e/o x
specificate;
• arrows(x0,y0,x1,y1,code=k,length=n,angle=m): disegna una freccia tra i
punti di coordinate (x0 , y0 ) e (x1 , y1 ). Quanto al parametro code: se code=1 la
freccia è disegnata nel punto (x0 , y0 ), se code=2 nel punto (x1 , y1 ) mentre se si
specifica code=3 si hanno due frecce, la prima in (x 0 , y0 ) e la seconda in (x1 , y1 ).
Il parametro length indica la lunghezza (in pollici) dei segmenti della freccia,
mentre angle ne determina la divaricazione.
• lines(x,y): permette di tracciare una “linea”, secondo i valori contenuti in x
e y, al grafico corrente;
• points(x,y): consente di aggiungere punti, in accordo alle coordinate specificate, al grafico corrente;
• segments(x0,y0,x1,y1): traccia un segmento di retta congiungente i punti di
coordinate (x0 , y0 ) e (x1 , y1 );
• text(x,y,stringa): permette di inserire, a partire dalle coordinate (x, y) specificate, il testo contenuto in stringa. Consigliamo all’utente di osservare
l’output generato dalle istruzioni:
> plot(1:20,type="n")
> for (i in (1:20)){text(i,i, letters[i])}
• title(main="...",xlab="...",ylab="...",): consente di inserire etichette
per il titolo del grafico, per l’asse della ascisse e per quello delle ordinate. Si noti
che occorre porre, al momento della creazione del grafico stesso, ann=FALSE.
2.3
Parametri grafici
Non sempre i grafici prodotti in modo automatico ed eventualmente arricchiti mediante le funzioni di “secondo livello” soddisfano le esigenze, ad esempio tipografiche,
dell’utente.
Egli, tuttavia, può agire direttamente sui parametri di default delle funzioni grafiche
di R, che, identificate da un nome proprio, definiscono ad esempio il tipo di caratteri,
lo stile delle linee e/o dei punti, la giustificazione del testo, il layout della finestra
grafica e molte cose ancora.
L’elenco completo dei nomi dei 68 parametri grafici si ottinene digitando .Pars:
64
E. D. Isaia, Linguaggio R e applicazioni statistiche
> .Pars
[1] "adj"
[6] "cex"
[11] "cin"
[16] "col.sub"
[21] "din"
[26] "font"
[31] "gamma"
[36] "mai"
[41] "mfrow"
[46] "omd"
[51] "ps"
[56] "tcl"
[61] "xaxs"
[66] "yaxs"
"ann"
"cex.axis"
"col"
"cra"
"err"
"font.axis"
"lab"
"mar"
"mgp"
"omi"
"pty"
"tmag"
"xaxt"
"yaxt"
"ask"
"cex.lab"
"col.axis"
"crt"
"fg"
"font.lab"
"las"
"mex"
"mkh"
"pch"
"smo"
"type"
"xlog"
"ylog"
"bg"
"cex.main"
"col.lab"
"csi"
"fig"
"font.main"
"lty"
"mfcol"
"new"
"pin"
"srt"
"usr"
"xpd"
"bty"
"cex.sub"
"col.main"
"cxy"
"fin"
"font.sub"
"lwd"
"mfg"
"oma"
"plt"
"tck"
"xaxp"
"yaxp"
mentre con par() si ottiene corrispondente lista dei valori di default. Desiderando
ottenere informazioni circa un parametro di interesse, possiamo impartire il comando
par("parametro"); ad esempio con:
> par("type")
[1] "p"
veniamo a sapere che per default la rappresentazione dei punti avviene in accordo
all’opzione type="p". Un’eventuale modifica dei parametri grafici può avvenire con
il comando par(parametro=nuovi valori); ad esempio:
> par(type="l")
> par("type")
[1] "l"
Prima di procedere a modifiche dei parametri di default, che come si è detto sono
contenuti in par(), conviene creare una copia degli stessi, sı̀ da ripristinarne, a fine
sessione, l’originale; ciò può avvenire, ad esempio, impartendo le istruzioni:
>
>
>
>
default.par<-par
... modifiche dei parametri ...
... rappresentazioni grafiche ad hoc ...
par(default.par)
Data la complessità dell’argomento, ci limitiamo ad elencare il comportamento dei
seguenti parametri:
65
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
• bg="colore": modifica il colore dello sfondo (“background”). Per default si
ha bg="white". I colori possibili, identificati da un nome e/o da un numero
progressivo, sono ben 657; il loro elenco si può ottenere con colors() oppure,
più elegantemente, con colours();
• cex=n: riduce o aumenta l’output grafico nella poporzione n specificata. Per
default cex=1;
• col="colore": modifica il colore dell’output grafico (linee, punti, ...); per
default si ha bg="white";
• fin=c(x,y): determina la dimensione, in pollici, dell’output grafico. La situazione di default prevede fin=c(5,5);
• font.lab=1, font.main=2: tipo dei caratteri per la rappresentazione delle
etichette per gli assi cartesiani e del titolo. Generalmente 1=testo normale,
2=grassetto, 3=corsivo e 4=corsivo grassetto;
• cex.lab=1, cex.main=1.2: ingrandimento dei caratteri per la rappresentazione
delle etichette per gli assi cartesiani e del titolo;
• lab=c(nx,ny): consente di modificare il numero delle etichette, “tickmarks”,
da apporre su entrambi gli assi di un grafico;
• lty="tipo": modifica il tipo di tratteggio nella rappresentazione di linee (“line
type”); la situazione di default prevede lty="solid". I tipi di tratteggio previsti, identificabili da un nome e/o da un numero progressivo da 0 a 6, sono,
nell’ordine, "blank", "solid", "dashed", "dotted" "dotdash", "longdash" e
"twodash";
• mfrow=c(r, s) consente di suddividere la finestra grafica in una matrice r x
s, i cui elementi saranno gli output generati dalle funzioni hist(), plot(), ...
La situazione di default viene ristabilita mediante mfrow=c(1, 1). Il comportamento di mfcol=c(r, s) è del tutto analogo;
• pch=n: modifica il tipo di simbolo impiegato per la rappresentazione delle coppie
di punti (x, y) della funzione plot(); n è un intero compreso tra 0 e 20. Per
default si ha pch=1;
• tmag=n: modifica la dimensione dei caratteri dei titoli, annotazioni, etichette,...
Per default si ha tmag=1.
• usr=c(x1, x2, y1, y2): indica le coordinate “estreme” della regione grafica;
per default si ha usr=c(0,1,0,1).
66
Capitolo 3
Argomenti di statistica descrittiva
Nel seguito vedremo come affrontare in R alcuni semplici argomenti di Statistica descrittiva quali la costruzione di istogrammi, diagrammi a barre, diagrammi a dispersione, diagrammi a “scatola e baffi”, la creazione di tabelle di frequenze per variabili
e/o mutabili statistiche sia univariate che bivariate, il calcolo alcuni indici di posizione
e/o di variabilità,
l’individuazione dei coefficienti di un modello di interpolazione a minimi quadrati,
il calcolo del coefficiente di correlazione lineare, l’individuazione dei parametri di una
retta di regressione, ...
Per comodità presenteremo i diversi problemi sottoforma di paragrafo *** comandi e
funzioni ad hoc*** , poi, faremo riferimento, di volta in volta, alle variabili contenute
negli archivi:
— stat1.txt: misurazioni della statura (cm) e del peso (Kg) di 100 coscritti;
— stat2.txt: numero di televisori e numero di autovetture posseduti da 50 famiglie;
— stat3.txt: reddito netto mensile, espresso in euro, percepito da 110 individui,
di cui 50 lavoratori autonomi e 60 lavoratori dipendenti;
— stat4.txt: titolo di studio (licenza elementare, licenza media superiore, diploma universitario e laurea), posizione professionale (operaio, impiegato e quadro)
e sesso di 50 dipendenti di una grande azienda;
— stat5.txt: numero (in migliaia di unità) degli occupati, suddivisi per sesso, in
Italia negli anni 1982 − 1990, fonte ISTAT;
— stat6.txt: voti, espressi in trentesimi, degli esami di Matematica Generale
e di Statistica di un gruppo di 40 studenti iscritti ad un corso di Diploma in
Economia.
che verranno acquisite in memoria via read.table(file="<nome del file>").
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
3.1
Mutabili e variabili statistiche univariate
Nel seguito vedremo come affrontare in R alcuni semplici argomenti di Statistica descrittiva quali la costruzione di istogrammi, diagrammi a barre, diagrammi a dispersione, diagrammi a “scatola e baffi”, la creazione di tabelle di frequenze per variabili
e/o mutabili statistiche sia univariate che bivariate, il calcolo alcuni indici di posizione
e/o di variabilità,
3.1.1
Costruzione di semplici tabelle di frequenze
La costruzione di semplici distribuzioni di frequenze, in termini assoluti e/o relativi,
per una mutabile o variabile statistica, le cui osservazioni individuali sono contenute
nell’oggetto x, avviene semplicemente utilizzando il comando table(x).
Tale modo di procedere può dare luogo a tabelle di difficile lettura e tale è il caso
qualora la mutabile o la variabile statistica in esame presenti un elevato numero di
modalità. In tali situazioni, com’è noto, si suole procedere ad una classificazione delle
modalità, ovvero raccogliere le osservazioni individuali in “classi”. In R ciò è possibile
ricorrendo al comando cut, la cui sintassi è:
cut(x,breaks=ncl,right=TRUE)
dove ncl indica appunto il numero delle classi desiderate 1 o, in alternativa, i limiti
superiori di classe, mentre con right=TRUE, ciascuna classe viene ad essere “chiusa a
destra”.
Esempio 3.1.1 Acquisite in memoria le due variabili contenute in stat1.txt mediante i
comandi:
> stat1<-read.table(file="stat1.txt")
> names(stat1)
[1] "altezza" "peso"
> attach(stat1)
ci proponiamo di visualizzarne la distribuzione di frequenze assolute. Con riferimento alla
sola variabile altezza, abbiamo:
> table(altezza)
altezza
164.7 166.3 167.2 167.4 167.8 167.9 168.5 169.1 169.2 169.3 169.4 170.6 170.8
1
1
1
1
1
1
1
1
1
1
1
1
1
171 171.3 171.4
172 172.6 173.6 173.8 174.2 174.5 174.6 174.9
175 175.4
1
In tal caso spetta ad R individuare l’ampiezza, costante, delle singole classi nonché i limiti inferiore
e superiore delle stesse.
68
E. D. Isaia, Linguaggio R e applicazioni statistiche
1
175.6
3
179.2
1
181.5
1
185.2
1
1
1
1
1
175.9
176 176.2 176.5
1
1
2
2
179.3 179.5 179.9
180
2
2
2
1
181.9
182 182.4 182.5
1
2
1
1
185.3 185.5 186.4 186.7
1
1
1
1
1
2
1
1
176.7
177 177.2 178.1
1
1
2
3
180.1 180.3 180.4 180.8
1
1
1
2
182.8 183.1 183.6 184.2
1
2
2
2
186.9 187.1 187.3 187.4
1
1
2
1
1
178.2
1
180.9
1
184.8
1
188.4
1
1
2
4
178.5 178.6 178.9
1
1
1
181.1 181.3 181.4
1
1
1
184.9
185 185.1
1
2
1
190.9
191 192.5
1
1
1
manifestamente di difficile lettura. Una migliore leggibilità la si ottiene raccogliendo i dati
individuali in classi, ad esempio, di egual ampiezza; scelto di raccogliere i dati individuali in
7 classi e lasciando a R individuare l’ampiezza ed i limiti di ciascuna di esse, avremo:
> table(cut(altezza,breaks=7))
(165,169] (169,173] (173,177] (177,181] (181,185] (185,189] (189,193]
7
11
22
22
19
16
3
Una via alternativa consiste nell’indicare il limite inferiore della prima classe, l’ampiezza di
classe ed il loro numero. Nel caso dell’altezza possiamo porre immaginare di raccogliere i dati
individuali in 7 classi di modulo 5 cm a partire da 165 cm. In tal caso:
> table(cut(altezza,breaks=160+5*(0:7)))
(160,165] (165,170] (170,175] (175,180] (180,185] (185,190] (190,195]
1
10
16
32
26
12
3
In sostanza, per le variabili in esame, definiti per chiarezza espositiva gli oggetti:
> (classi.alt<-160+5*(0:7))
[1] 160 165 170 175 180 185 190 195
> (classi.peso<-70+5*(0:5))
[1] 70 75 80 85 90 95
abbiamo:
> table(cut(altezza,breaks=classi.alt))
(160,165] (165,170] (170,175] (175,180] (180,185] (185,190] (190,195]
1
10
16
32
26
12
3
> table(cut(peso,breaks=classi.peso))
(70,75] (75,80] (80,85] (85,90] (90,95]
12
31
41
15
1
69
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Qualora si operi su variabili statistiche, potrebbe essere interessante ripartire i valori individuali in tre classi a seconda che essi cadano entro il primo quartile, tra il primo ed il terzo,
oltre il terzo; a tal fine, abbiamo approntato la seguente funzione ad hoc:
> classi.speciali<-function(x)
{
as.real(c(min(x),quantile(x,prob=.25),
quantile(x,prob=.75),max(x)))
}
la quale ci consente di ottenere, per le variabili in esame, le seguenti distribuzioni di frequenze:
> table(cut(altezza,breaks=classi.speciali(altezza)))
(165,175] (175,183] (183,192]
24
50
25
> table(cut(peso,breaks=classi.speciali(peso)))
(70.6,76.8] (76.8,84.1] (84.1,91.5]
25
49
25
Ciò facendo possono evidentemente ottenersi distribuzioni di frequenze con classi di modulo
non necessariamente costante.
♥
A volte capita che alle osservazioni di un carattere di interesse sia asssociata una
variabile di stratificazione; ad esempio:
— la statura in funzione del sesso;
— il reddito annuo lordo in funzione del numero dei componenti il nucleo familiare;
— il rapporto tra prezzo ed utile di titoli azionari su diverse borse;
— ...
Se tale è il caso, possiamo immaginare di suddividere le osservazioni individuali del
carattere in tanti gruppi quanti indicato dalle modalità assunte dalla variabile di
stratificazione f; a ciò sopperisce, appunto, il comando split, la cui sintassi è:
split(x,f)
dove f è generalmente un oggetto a valori numerici interi consecutivi di lunghezza
pari a length(x), ovvero esso protrebbe possedere modalità factor.
In ogni caso con split viene creata una lista i cui elementi sono gli elementi contenuti
in x in corrispondenza a ciascuna modalità della stessa.
70
E. D. Isaia, Linguaggio R e applicazioni statistiche
Esempio 3.1.2 L’archivio stat3.dat contiene, sottoforma di data frame, i valori del reddito
netto mensile, espresso in euro, percepito da 110 individui, di cui 50 lavoratori autonomi e
60 lavoratori dipendenti. L’archivio in questione è strutturato in modo che la prima colonna
riporti le misurazioni dei redditi e la seconda una variabile di tipo “flag” che assume valore 1
se il reddito proviene da lavoro autonomo e valore 2 se esso proviene da lavoro dipendente.
Aquisiti i dati individuali mediante le istruzioni:
> redditi<-read.table(file="stat3.txt")
> names(redditi)
[1] "reddito"
"posizione"
> attach(redditi)
e desiderando, nel seguito, analizzare separatamente la distribuzione dei redditi dei lavoratori
autonomi e quella dei lavoratori dipendenti, sfruttando la funzione split, che porgerebbe:
> split(reddito,posizione)
$"1"
[1] 1949 1967 1797 1812 1855
[14] 1801 1810 2020 2105 1767
[27] 1929 1909 1868 2079 1793
[40] 1906 2103 1616 1939 1703
1698
2011
1897
1593
1855
1986
1977
1782
1703
1977
1672
1979
1989
1882
2012
1630
1865
1911
1875
1761
2099 2054 2080
1868 1672 1963
1689 1820 1631
1761
$"2"
[1]
[14]
[27]
[40]
[53]
1430
1548
1551
1624
1371
1479
1468
1202
1392
1419
1357
1532
1285
1239
1178
1559
1435
1177
1492
1625
1535
1886
1078
1420
1306
1604
1530
1182
1688
1532
1249
1396
1652
1475
1084
1720
1524
1495
1386
1602
1098
1418
1770
1750
1524
1600
1548
1654
1629
1563
1301
1367
1858
1228
1785
1443
1400
1191
1428
1566
possiamo creare i due nuovi oggetti:
> reddito.aut<-split(reddito,posizione)$"1"
> reddito.dip<-split(reddito,posizione)$"2"
su cui sarà possibile operare, ad esempio:
> table(cut(reddito.aut,breaks=1550+150*(0:4)))
(1550,1700] (1700,1850] (1850,2000] (2000,2150]
8
12
21
9
♥
71
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
3.1.2
Rappresentazioni grafiche
Parallelamente alla presentazione di tabelle di frequenze, il comportamento del carattere statistico sotto esame può essere riassunto mediante opportuni grafici, ricordando
che in linea di massima:
— per le mutabili statistiche si fa ricorso a semplici diagrammi a barre ovvero a
diagrammi circolari o a torta;
— per le variabili statistiche si ricorre ad istogrammi o a diagrammi a bastoncini,
a seconda che la variabile sia di tipo continuo o discreto.
Inlotre, nel caso si operi su variabili statistiche, può essere interessante evidenziare
l’andamento della funzione delle frequenze cumulate oppure ricorrere a semplici “boxplot”, o diagrammi a “scatola e baffi”; com’è noto, tali rappresentazioni grafiche
offrono informazioni intuitive circa i quantili, la variabilità e l’eventuale simmetria
della distribuzione del carattere in esame.
Esempio 3.1.3 Con riferimento alla variabile statistica altezza di cui all’Esempio 3.1.1,
mantenendo il raggruppamento in classi:
> (classi.alt<-160+5*(0:7))
[1] 160 165 170 175 180 185 190 195
l’istogramma di frequenze relative e la funzione delle frequenze relative cumulate, riportati in
figura (3.1), sono ottenuti mediante le istruzioni:
1
2
3
4
5
6
7
8
9
10
> fcum.classi.alt<-c(0,cumsum(table(cut(altezza,breaks=classi.alt)))
/length(altezza))
> par(mfrow=c(1, 2))
> hist(altezza,breaks=classi.alt,probability=TRUE,col="light yellow",
main="",xlab="Classi di altezza",ylab="Frequenze relative")
> plot(classi.alt,fcum.classi.alt,col="blue",xlab="Classi di altezza",
ylab="Frequenze relative cumulate",main="",frame.plot=FALSE)
> lines(classi.alt,fcum.classi.alt,col="red")
> grid()
> par(mfrow=c(1, 1))
A commento, si noti che:
— al fine della rappresentazione grafica della funzione delle frequenze relative cumulate
della variabile statistica in esame, occorre dapprima procedere al calcolo 2 delle frequenze
relative cumulate, calcolate, linee [1]-[2], ricorrendo alle funzioni cumsum(variabile) e
length(variabile);
2
Perlomeno per motivi di chiarezza espositiva.
72
0.8
0.6
0.4
0.0
0.2
Frequenze relative cumulate
0.04
0.02
0.00
Frequenze relative
0.06
1.0
E. D. Isaia, Linguaggio R e applicazioni statistiche
160
170
180
190
160
Classi di altezza
170
180
190
Classi di altezza
Figura 3.1: Istogramma e funzione di frequenze cumulate — Esempio 3.1.2
— desiderando rappresentare sul piano cartesiano anche i punti di coordinate del tipo
(u, w), dove u rappresentano gli estremi superiori di classe e w i valori delle frequenze
relative cumulate, converrà dapprima rappresentare tali punti e successivamente, tramite il comando lines(), tracciare la spezzata che li congiunge. Si osservino le istruzioni
in linea [6], [7] e [8].
A risultati simili a quelli sopra descritti saremmo potuti giungere mediante l’istruzione:
> plot(classi.alt,fcum.classi.alt,type="b")
lasciandone al Lettore la verifica sul campo.
♥
Esempio 3.1.4 Con riferimento alle variabile statistica reddito.aut definita all’Esempio
3.1.2, i comandi che seguono producono gli istogrammi proposti in figura (3.2):
> par(mfrow=c(1,2))
> hist(reddito.aut,probability=TRUE,col="light yellow",
main="",xlab="Calssi di reddito",ylab="Frequenze relative")
> hist(reddito.aut,breaks=c(1500,1700,1800,2000,2150),col="light yellow",
main="",xlab="Calssi di reddito",ylab="Frequenze relative")
> par(mfrow=c(1,1))
di immediata interpretazione.
♥
73
0.0020
0.0000
0.0010
Frequenze relative
0.0020
0.0010
0.0000
Frequenze relative
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
1500
1700
1900
2100
1500
Calssi di reddito
1700
1900
2100
Calssi di reddito
Figura 3.2: Istogrammi con classi a modulo costante e non costante— Esempio 3.1.3
Esempio 3.1.5 Sempre con riferimento alle variabili reddito.aut e reddito.dip introdotte
all’Esempio 3.1.2, il grafico a “scatola e baffi” riprodotto in figura (3.3) ed ottenuto mediante
le istruzioni:
> boxplot(reddito.aut,reddito.dip,reddito,col="light yellow",
names=c("Autonomo","Dipendente","Autonomo+Dipendente"))
evidenzia come ci si trovi in presenza di due diverse distribuzioni dei redditi. In particolare,
si noti come la distribuzione dei redditi da lavoro autonomo sia tutta spostata verso l’alto
rispetto a quella dei redditi da lavoro dipendente. Inoltre, mentre entrambe le distribuzioni
tendano ad essere simmetriche (si noti la posizione delle rispettive mediane all’interno della
“scatola”), i redditi da lavoro dipendente mostrano una maggiore variabilità.
Volutamente il grafico di figura (3.3) riporta anche il “boxplot” relativo alla variabile reddito.
I “diagrammi a scatola e baffi” delle sole due variabili reddito.aut e reddito.dip possono
essere ottenuti in modo diretto tramite il comando:
> boxplot(reddito.aut,reddito.dip,names=c("Autonomo","Dipendente"))
o, alternativamente:
74
1200
1400
1600
1800
2000
E. D. Isaia, Linguaggio R e applicazioni statistiche
Autonomo
Dipendente
Autonomo+Dipendente
Figura 3.3: Diagramma a “scatola e baffi” — Esempio 3.1.5
> boxplot(split(reddito,posizione),names=c("Autonomo","Dipendente"))
cioè senza dovere introdurre le variabili reddito.aut e reddito.dip
♥
Esempio 3.1.6 Per cose ormai note, introdotto per comodità l’oggetto:
> x<-nchar(apropos(".",mode="function"))
il successivo comando table(x) porge la distribuzione, in termini di frequenze assolute, del
numero di caratteri delle funzioni definite in R:
> table(x)
x
1
2
3
24 34 59
18 19 20
29 14 18
4
5
6
7
8
9
85 115 122 129 104 114
21 22 23 24 26
13
3
2
1
1
10
91
11
90
12
82
13
70
14
51
15
42
16
32
17
25
La distribuzione di tale variable discreta può essere riassunta graficamente mediante un diagramma a bastoncini e, per completezza, la corrispondente funzione delle frequenze relative
cumulate; a tal fine sono sufficienti le istruzioni:
75
0
0.8
0.6
0.4
0.0
0.2
80
60
40
20
Frequenze assolute
100
Frequenze relative cumulate
120
1.0
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
1
4
7 10
14
18
22
26
0
Numero di caratteri
5
10
15
20
25
Classi di altezza
Figura 3.4: Diagramma a bastoncini e funzione cumulativa — Esempio 3.2.1
> fcum.x<-cumsum(table(x))/length(x)
> par(mfrow=c(1,2))
> plot(table(x),type="h",main="",xlab="Numero di caratteri",
ylab="Frequenze assolute",col="blue")
> plot(sort(unique(x)),fcum.x,main="",xlab="Classi di altezza",
ylab="Frequenze relative cumulate",type="s",col="blue")
> par(mfrow=c(1,1))
che producono i grafici desiderati riportati in figura (3.4).
♥
A conclusione del paragrafo, osserviamo che qualora si operi con variabili statistiche
continue, l’istogramma costituisce un’approssimazione della “curva di densità”, diciamo f (x), che caratterizza la variabile in esame; immaginando che le classi abbiano
ampiezza costante h, tale approssimazione avviene attribuendo a tutti i punti x ∈ IR
appartenenti alla i-esima classe, il medesimo valore n i /n h. Sotto tale profilo, appare evidente come la determinazione del numero delle classi sia quanto mai delicata;
un numero di classi esiguo comporta in genere una perdita di informazione mentre
un numero elevato di classi può produrre grafici incoerenti, ad esempio alcune classi
potranno avere frequenze nulle o quasi.
Un diverso approccio al problema ci è offerto da quelle tecniche che in Statistica vanno
sotto il nome di teoria della stima non parametrica di una densità; su tal argomento
76
E. D. Isaia, Linguaggio R e applicazioni statistiche
si possosno consultare i testi introduttivi di Bowman, Azzalini (1997) e Wand, Jones
(1995).
Senza entrare in dettagli, vale qui la pena accennare, perlomeno dal punto di vista
operativo, al cosidetto metodo della finestra mobile o della stima a kernel, secondo il
h
quale in corrispondenza ad un prefissato x ∈ IR si costruisce una classe ]x − h
2 ; x + 2 [,
di ampiezza appunto h e, indicando con n x il numero delle osservazioni individuali che
cadono nella classe stessa, l’approssimazione di f (x) verrà data dal rapporto n x /n h;
naturalmente iterando tale processo su tutto IR si perverrà all’approssimazione fˆ(x)
di f (x). Generalizzando, si potrebbe dimostrare che fˆ(x) soddisfa la relazione:
1
x − xi
fˆ(x) =
K(
)
nh
h
dove K, detta funzione kernel, è la funzione indicatrice in ] − 1/2; 1/2[ e pertanto
K(u) = 1 per −1/2 ≤ u < 1/2.
In pratica, si preferisce ricorrere a funzioni kernel che offrano una migliore “lisciatura”
per fˆ(x); tra queste citiamo il kernel gaussiano, per cui K(u) = (2 π) −1 exp −u2 /2.
Ovviamente, resta aperto, come nel caso dell’approssimazione mediante un istogramma, il problema della scelta di h. A tal proposito la letteratura specialistica abbonda
di proposte di metodi analitici ed empirici; per dettagli si rimanda ancora ai testi di
Bowman, Azzalini (1997) e Wand, Jones (1995) ed alla bibliografia ivi citata.
In R è possibile eseguire una siffatta analisi ricorrendo alla funzione density, la cui
sintassi minima, supponendo che le osservazioni individuali del carattere continuo in
esame siano raccolte nell’oggetto x, è:
density(x)
che, ricorrendo per default ad una funzione kernel gaussiana, e visualizza alcune informazioni circa la variabile di input, il valore proposto per h, nonché alcune misure
riassuntive sui 512 valori x e i corrispondenti valori di ordinata y = fˆ(x). Questi, in
particolare, possono essere estratti dalla lista creata dalla funzione stessa con i consueti comandi density(x)$x e density(x)$y ed utilizzati per altri fini, ad esempio
la visualizzazione della funzione fˆ(x) mediante l’istruzione:
> plot(density(x)$x,density(x)$y)
Esempio 3.1.7 Riprendendo i dati relativi ai redditi e contenuti in stat3.txt:
> redditi<-read.table(file="stat3.txt")
> attach(redditi)
77
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
1800
2200
0.0012
1000
1400
1800
Classi di reddito
(c) 12 classi - modulo = 100
(d) 15 classi - modulo = 80
1800
2200
Classi di reddito
0.0006
Frequenze relative
1400
2200
0.0012
Classi di reddito
0.0000
1000
0.0006
Frequenze relative
0.0006
0.0000
1400
0.0012
1000
0.0000
0.0012
(b) 8 classi - modulo = 150
0.0006
Frequenze relative
0.0000
Frequenze relative
(a) 6 classi - modulo = 200
1000
1400
1800
2200
Classi di reddito
Figura 3.5: Istogrammi della distribuzione dei redditi — Esempio 3.2.2
la figura (3.5) riporta alcuni istogrammi per la variabile reddito costruiti ipotizzando quattro
diversi raccoglimenti in classi dei dati individuali; in particolare l’istogramma (c) suggerisce un
comportamento bimodale della distribuzione in esame, il che fa supporre di essere in presenza
di due diverse distribuzioni quanto a parametri di scala e, probabilmente, di variabilità.
Alle stesse conclusioni saremmo giunti effettuando una “stima a kernel” mediante la funzione
density; infatti il comportamento bimodale della distribuzione dei redditi viene evidenziato
dai grafici riportati in figura (3.6), ottenuti mediante le istruzioni:
1
2
3
4
5
6
7
8
> par(mfrow=c(1,2))
> plot(density(reddito),main="Kernel normale - h = 92.55",xlab="Reddito",
ylab="",col="red",cex.main=1,font.main=1,frame.plot=FALSE)
> hist(reddito,breaks=12,probability=TRUE,main="",
xlab="Classi di reddito",ylab="",col="light yellow",cex.main=1,
font.main=1,xlim=c(min(density(reddito)$x),max(density(reddito)$x)))
> lines(density(reddito)$x,density(reddito)$y,type="l",col="red")
> par(mfrow=c(1,1))
78
E. D. Isaia, Linguaggio R e applicazioni statistiche
0.0000
0.0000
0.0004
0.0004
0.0008
0.0008
0.0012
0.0012
Kernel normale - h = 92.55
1000
1500
2000
1000
Reddito
1500
2000
Classi di reddito
Figura 3.6: Stima a kernel della distribuzione dei redditi — Esempio 3.2.2
a commento delle quali, ci limitiamo ad osservare che, a parte alcune consuete opzioni di
formato (main="...", xlab="...", ..., frame.plot=...):
ˆ
— in riga [2] e [3] si richiede il grafico di f(x)
nella forma plot(density(reddito)), in
alternativa a:
plot(density(reddito)$x,density(reddito)$y,type="l",...)
— le righe [4], [5] e [6] consentono di visualizzare l’istogramma, articolato su 12 classi a
modulo costante, della variabile in esame, nell’intervallo:
xlim=c(min(density(reddito)$x),max(density(reddito)$x))
ˆ
— in riga [7], infine, all’istogramma viene sovraimposto il grafico di f(x).
Si noti che, in “modo automatico”, R propone quale valore per h:
> density(reddito)$bw
[1] 92.54717
Valori maggiori o minori di h produrrebbero, come emerge dai grafici riportati in figura (3.7),
curve o troppo “liscie” o troppo “aderenti” alle osservazioni individuali.
♥
79
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
0.0010
0.0005
0.0000
0.0000
0.0005
0.0010
0.0015
Kernel normale - h = 30
0.0015
Kernel normale - h = 200
500
1000
1500
2000
2500
1000
Reddito
1400
1800
2200
Reddito
Figura 3.7: Stime a kernel della distribuzione dei redditi — Esempio 3.2.2
3.1.3
Su alcune misure di sintesi
Sulle principali funzioni statistiche, per cosı̀ dire “primitive”, si è già detto in (1.2.5),
pertanto nel seguito affronteremo alcuni problemi specifici che porteranno alla creazione di funzioni ad hoc o all’impiego di particolari funzioni predefinite.
La funzione stat.base
In molti casi, potrebbe essere di qualche utilità, perlomeno nella prima fase di descrizione di un carattere statistico quantitativo, disporre di una semplice funzione che,
a seconda del vettore di dati in ingresso, calcoli e visualizzi le principali misure di
posizione e di variabilità. Tale funzione, a cui daremo il nome stat.base, potrebbe
assumere la forma:
1
2
3
4
5
6
7
stat.base <-function(x,digits=4)
{
n.oss<-length(x)
ris<-c(1:10)
ris[1]<-round(mean(x),digits)
ris[2]<-round(median(x),digits)
ris[3]<-round(quantile(x,0.25),digits)
80
E. D. Isaia, Linguaggio R e applicazioni statistiche
ris[4]<-round(quantile(x,0.75), digits)
ris[5]<-round(quantile(x,0.75)-quantile(x,0.25),digits)
ris[6]<-round(max(x)-min(x), digits)
ris[7]<-round(var(x)*(sum(x)-1)/(sum(x)),digits)
ris[8]<-round((var(x)*(sum(x)-1)/(sum(x)))^.5,digits)
ris[9]<-round(sum(x),digits)
ris[10]<-round(var(x)*(sum(x)-1),digits)
ris<-matrix(ris,ncol=1)
dimnames(ris)<-list(c("Media","Mediana:","I quartile:",
"III quartile:","Diff. Interquartile:","Range:","Varianza:",
"S.q.m.:","Somma:","Devianza"),"")
cat("Vettore dei dati individuali: ", deparse(substitute(x)),
"\nOsservazioni: ", n.oss,
"\n--------------------","\nStatistiche:","\n")
return(ris)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
}
A commento, si osservi:
— il ricorso alla definizione del vettore ris i, cui elementi sono ris[i] con evidentemente i = 1, 2, . . . , 10;
— l’impiego della funzione dimnames(ris) quale lista contenente le stringhe di
identificazione di ciascun risultato proposto;
— l’uso della funzione deparse(substitute(x)) che fa apparire a fianco dell’etichetta "Vettore dei dati individuali:" il vero nome della variabile oggetto
di studio;
— l’impiego di round(oggetto,digits) dove, per default, si ha digits=4; situazione che potrebbe essere modificata ricorrendo a stat(oggetto,digits=n),
con n intero positivo.
Esempio 3.1.8 Con riferimento alla sola variabile altezza contenuta in stat1.txt, il ricorso
alla funzione stat.base produrrebbe:
> stat1<-read.table(file="stat1.txt")
> attach(stat1)
> stat.base(altezza)
Vettore dei dati individuali: altezza
Osservazioni: 100
-------------------Statistiche:
81
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Media
178.5150
Mediana:
178.7500
I quartile:
174.9750
III quartile:
182.8750
Diff. Interquartile:
7.9000
Range:
27.8000
Varianza:
36.8736
S.q.m.:
6.0724
Somma:
17851.5000
Devianza
658248.4568
> detach(stat1)
♥
Le differenze assolute medie
In R non è implementata alcuna funzione che permetta il calcolo delle differenze
assolute medie con (o senza) ripetizione, sicché l’utente è obbligato a ricorrere ad una
funzione creata ad hoc.
Ricordando che, operando sui dati individuali x α , α = 1, 2, . . . n, le differenze assolute
medie sono definite come:
∆R =
!n
α=1
!n
β=1
2
|xα − xβ |
∆=
n
!n
α=1
!n
β=1
|xα − xβ |
n (n − 1)
a seconda che esse siano, rispettivamente, con o senza ripetizione, a fini operativi sarà
sufficiente calcolare la quantità posta a numeratore, la quale può essere posta nella
forma:
(3.1)
1 D 1t
dove D indica la matrice quadrata delle differenze in modulo |x α − xβ |, cioè:

|x1 − x1 |


...


D =  |xα − x1 |

...

|xn − x1 |
. . . |x1 − xβ |
...
...
. . . |xα − xβ |
...
...
. . . |xn − xβ |

. . . |x1 − xn |


...
···

. . . |xα − xn | 


...
···

. . . |xn − xn |
mentre 1 è un vettore riga ad elementi unitari.
Ciò premesso, osservando che la (3.1) equivale al calcolo della somma degli elementi di
D ed ipotizzando che le n osservazioni individuali del carattere quantitaivo in esame
siano raccolte nell’oggetto x, si possono impartire direttamente i comandi:
82
E. D. Isaia, Linguaggio R e applicazioni statistiche
1
2
3
4
x<-rbind(x)
s.dif<-sum(abs(matrix(outer(x,x,"-"),ncol(x),ncol(x))))
s.dif/length(x)^2
s.dif/(length(x)*(length(x)-1))
a commento dei quali osserviamo:
— in riga [1] si ridefinisce x quale vettore riga;
— in riga [2] si procede al calcolo della (3.1), il cui risultato viene inserito nell’oggetto s.dif. Si noti che la matrice D viene individuata mediante la semplice
istruzione:
abs(matrix(outer(x,x,"-"),ncol(x),ncol(x)))
— le righe [3] e [4] porgono, rispettivamente, le differenze assolute medie con
ripetizione e senza ripetizione.
Esempio 3.1.9 Posto che x contenga gli interi consecutivi da 1 a 4, abbiamo:
> x<-rbind(1:4)
> s.dif<-sum(abs(matrix(outer(x,x,"-"),ncol(x),ncol(x))))
> s.dif/length(x)^2
[1] 1.25
> s.dif/(length(x)*(length(x)-1))
[1] 1.666667
In particolare:
> abs(matrix(outer(x,x,"-"),ncol(x),ncol(x)))
[,1] [,2] [,3] [,4]
[1,]
0
1
2
3
[2,]
1
0
1
2
[3,]
2
1
0
1
[4,]
3
2
1
0
> sum(abs(matrix(outer(x,x,"-"),ncol(x),ncol(x))))
[1] 20
come il Lettore può facilmente verificare.
♥
Qualora l’utente non disponesse dei dati individuali x α , ma unicamente della distribuzione di frequenze {xi , ni }i=1,2,...,k del carattere quantitativo in esame, allora la
83
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
quantità posta a numeratore delle differenze assolute medie con o senza ripetizione
risulterebbe:
k !
k
!
i=1 j=1
|xi − xj | ni nj
e in tal caso si tratterà di calcolare:
(3.2)
n D nt
dove D indica la matrice quadrata, di dimensione k × k, delle differenze in modulo
|xi − xj |, mentre n è un vettore riga i cui k elementi corrispondono alle frequenze
assolute ni . Quindi, ipotizzando che gli oggetti xi e ni contengano, rispettivamente,
le k modalità quantitative del carattere in esame e le corrispondenti frequenze assolute,
si possono impartire direttamente i comandi:
>
>
>
>
>
xi<-rbind(xi)
ni<-rbind(ni)
s.dif<-ni%*%abs(matrix(outer(xi,xi,"-"),ncol(xi),ncol(xi)))%*%t(ni)
s.dif/sum(ni)^2
s.dif/(sum(ni)*(sum(ni)-1))
Ciò premesso, la funzione difemedie che segue si occupa del calcolo delle differenze
assolute medie con e senza ripetizione e ciò indipendentemente dal fatto che quale
input si immetta il solo vettore x delle osservazioni individuali oppure i due vettori, x
e ni contenenti, rispettivamente, le k modalità rilevate del carattere e le corrispondenti
frequenze assolute:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
difmedie<-function(x,ni,decimali=4,print.out=TRUE)
{
if (!is.matrix(x)){x<-rbind(x)}
if (missing(ni)){ni<-rep(1,length(x))}
if (!missing(ni) && !is.matrix(ni)){ni<-rbind(ni)}
s.dif<-ni%*%abs(matrix(outer(x,x,"-"),ncol(x),ncol(x)))%*%t(ni)
delta.cr<-s.dif/sum(ni)^2
delta.sr<-s.dif/(sum(ni)*(sum(ni)-1))
if (print.out)
{
cat("
Dif. medie CR -> ",round(delta.cr,decimali),"\n")
cat("
Dif. medie SR -> ",round(delta.sr,decimali),"\n")
}
invisible(list(D.cr=as.real(delta.cr),D.sr=as.real(delta.sr)))
}
84
E. D. Isaia, Linguaggio R e applicazioni statistiche
A commento della funzione proposta:
— in riga [3] si controlla che l’oggetto in entrata sia un vettore; in caso contrario
si provvede alla sua trasformazione locale;
— in riga [4], si crea, qualora non sia stato definito in modo esplicito, il vettore
unitario ni, mentre in riga [5], verificata l’esistenza dell’oggetto in entrata ni
contenente le frequenze assolute, lo si trasforma, se è il caso, in un vettore;
— in riga [6] si procede al calcolo della (3.2), mentre le righe [7] e [8] si occupano
del calcolo delle differenze assolute medie con ripetizione (delta.cr) e senza
ripetizione (delta.sr);
— in riga [9] il controllo if (print.out) consente di visualizzare i risultati, a
patto che print.out=TRUE (situazione di default);
— le righe [11] e [12] visualizzano i risulati desiderati;
— in riga [14] viene creata una lista contenente i risultati che può servire a visualizzare, e se è il caso utilizzare per successive elaborazioni, uno dei due oggetti
delta.cr o delta.cr.
Esempio 3.1.10 A puro scopo didattico, si immagini che da un’indagine effettuata su 60
automobilisti italiani, al fine di indagare circa il numero di infrazioni al Codice della Strada
commesse nel corso dell’anno corrente, risultino i seguenti valori individuali:
0
1
0
1
0
0
0
3
0
0
1
3
4
0
0
4
4
1
0
0
0
7
0
0
0
1
2
1
0
0
0
2
0
0
0
0
0
3
1
1
0
0
1
0
0
0
0
4
2
0
0
0
0
0
0
0
1
0
0
0
Definito l’oggetto x contenente le 60 osservazioni e sfruttando la funzione difemedie, abbiamo:
> x<-c(0,1,0,0,4,4,0,7,0,1,0,0,0,1,1,0,2,0,0,0,1,0,3,1,0,4,0,0,1,0,
2,0,3,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,2,0,0,0,1,0,0,4,0,0,1,0)
> difmedie(x)
Dif. medie CR -> 1.2367
Dif. medie SR -> 1.2576
Dal momento che la distribuzione di frequenze del carattere in esame è:
> table(x)
x
0 1 2 3
39 10 3 3
4
4
7
1
85
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
saremmo giunti agli stessi risultati definendo gli oggetti xi e ni contenenti le k = 6 modalità
del carattere e le corrispondenti frequenze assolute, infatti:
> (xi<-sort(unique(x)))
[1] 0 1 2 3 4 7
> (ni<-as.real(table(x)))
[1] 39 10 3 3 4 1
> difmedie(xi,ni)
Dif. medie CR -> 1.2367
Dif. medie SR -> 1.2576
Si noti che, desiderando visualizzare unicamente la differenza assoluta media con ripetizione,
potremmo, a questo punto, impartire indifferentemente i comandi:
> difmedie(x,print.out=FALSE)$D.cr
[1] 1.236667
> difmedie(xi,ni,print.out=FALSE)$D.cr
[1] 1.236667
ottenendo, coerentemente, gli stessi risultati.
♥
Sulla stratificazione
Come già si osservò, a volte capita che le n osservazioni individuali di un carattere
possano essere ripartite in più gruppi (o “strati”) a seconda dalle modalità assunte
da una variabile di stratificazione.
Nel seguito vedremo come sia possibile, qualora di operi con un carattere quantitativo,
ottenere le più comuni misure di posizione e di variabilità per ciascun strato. A tal fine,
per scioltezza espositiva, supporremo che le n osservazioni individuali del carattere
in esame siano raccolte nell’oggetto x e che flag contenga le k ≤ n modalità, non
necessariamente numeriche, della variabile di stratificazione.
Un primo modo di procedere consiste ovviamente nel creare, ricorrendo al comando
split, tante nuove variabili quante indicato dalla variabile di stratificazione e su
ciascuna di esse applicare la funzione statistica di interesse.
Agli stessi risutlati, ma in modo più “elegante”, si può giungere sfruttando le funzioni
tapply o sapply, le cui sintassi, perlomeno nella veste più dimessa, si presentano:
tapply(x,flag,funzione)
sapply(split(x,flag),funzione)
dove funzione è, in linea di massima, una qualsiasi funzione predefinita o eventualmente definita dall’utente.
Un terzo modo di risolvere il problema consiste nel ricorso alla funzione aggregate,
la cui sintassi minima è:
86
E. D. Isaia, Linguaggio R e applicazioni statistiche
aggregate(x,list(flag),funzione)
la quale, sfruttando la funzione tapply, porge i risultati desiderati in forma tabellare.
L’esempio che segue illustra i tre diversi approcci testé descritti.
Esempio 3.1.11 A puro scopo didattico, si immagini che su un un collettivo costituito 14 studenti universitari, di cui 8 di sesso maschile, si sia rilevato il voto conseguito ad un particolare
esame di profitto; definiti gli oggetti elementari:
voto<-c(23,27,27,30,25,20,27,27,18,27,27,30,30,23)
sesso<-c("M","M","M","M","M","M","M","M","F","F","F","F","F","F")
aggregate(stat,list(sex),mean)
ci proponiamo di calcolare il voro medio in funzione del sesso:
— introducendo due nuove varibili:
> (femmine<-split(voto,sesso)$"F")
[1] 18 27 27 30 30 23
> (maschi<-split(voto,sesso)$"M")
[1] 23 27 27 30 25 20 27 27
> mean(femmine)
[1] 25.83333
> mean(maschi)
[1] 25.75
— ricorrendo alla funzione tapply:
> tapply(voto,sesso,mean)
F
M
25.83333 25.75000
per cui il voto medio dei maschi è:
> as.real(tapply(voto,sesso,mean)[2])
[1] 25.75
— sfruttando la funzione sapply:
> sapply(split(voto,sesso),mean)
F
M
25.83333 25.75000
per cui il voto medio delle femmine risulta:
> as.real(sapply(split(voto,sesso),mean)[1])
[1] 25.83333
87
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
— ricorrendo alla funzione aggregate:
> aggregate(voto,list(sesso),mean)
Group.1
x
1
F 25.83333
2
M 25.75000
per cui il voto medio dei maschi è:
> as.real(aggregate(voto,list(sesso),mean)[2,2])
[1] 25.75
♥
Sui valori mancanti
Se un oggetto contiene valori mancanti, classificati come NA (acronimo di “Not Available”) l’applicazione delle funzioni statistiche comporta alcuni problemi poiché essi,
per default, vengono conteggiati in length(oggetto). In effetti le funzioni in questione tengono conto della possiblità di escludere i valori mancanti; ad esempio la
funzione mean è definita:
mean<-function(x,na.rm=FALSE)
{
if(na.rm) {x<-x[!is.na(x)]}
else if(any(is.na(x))) {return(NA)}
sum(x)/length(x)
}
sicché è sufficiente modificare la situazione di default na.rm=FALSE in na.rm=TRUE.
Ad esempio:
> x<-c(NA,12,NA,14,15,17,21)
> mean(x)
[1] NA
> mean(x,na.rm=TRUE)
[1] 15.8
Nel seguito proponiamo due semplici alternative che a nostro avviso permettono un
maggior controllo dei valori mancanti.
Le funzioni off.na(x) e rep.na(x) consentono di modificare un oggetto che presenta
elementi mancanti (NA). La prima funzione si limita ad eliminarli, mentre la seconda
sostituisce tali valori con il valor medio o, a discrezione dell’utente, con la mediana di
x. *** Per comodità i nuovi valori in uscita sono messi negli oggetti w.off e w.rep
rispettivamente. I listati delle due funzioni sono:
88
E. D. Isaia, Linguaggio R e applicazioni statistiche
1
off.na<-function(x){x<-x[!is.na(x)]}
Cosı̀ ad esempio:
> x<-c(NA,12,NA,14,15,17,21)
> mean(off.na(x))
[1] 15.8
1
2
3
4
5
6
7
rep.na<-function(x, media=TRUE)
{
if (!media){valore<-median(x[!is.na(x)])}
else {valore<-mean(x[!is.na(x)])}
for (i in (1:length(x))){if (is.na(x[i])==TRUE) {x[i]<-valore}}
x<-x
}
> rep.na(x)
The new w.rep object has been created
> w.rep
[1] 15.8 12.0 15.8 14.0 15.0 17.0 21.0
> rep.na(x,media=FALSE)
The new w.rep object has been created
> w.rep
[1] 15 12 15 14 15 17 21
3.1.4
3.2
Sulla concentrazione
Mutabili e variabili statistiche bivariate
3.2.1
Tabelle di frequenze doppie
3.2.2
L’indice di dipendenza chi-quadro
3.2.3
L’indice di dipendenza in media
3.2.4
Sulla correlazione lineare
Esempio 3.2.1 Con riferimento alle variabili qualitative contenute in stat4.dat, ci proponiamo di costruire la distribuzione congiunta del titolo di studio (studio) e della posizione
professionale (posizio) dei 50 individui intervistati. Acquisiti i dati mediante le consuete
istruzioni:
> esempio4<-read.table(file="stat4.txt")
> names(esempio4)
89
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
[1] "studio" "posizio" "sex"
> attach(esempio4)
la distribuzione congiunta di frequenze assolute desiderata la si ottiene mediante l’istruzione:
> table(studio,posizio)
posizio
studio 0 1 2
0 10 1 1
1 6 14 1
2 0 10 3
3 0 1 3
Desiderando migliorare la leggibilità della tabella proposta, possiamo ricorrere ai comandi
array() e dimnames(); infatti, impartite le istruzioni:
>tutti<-array(table(studio,posizio),c(length(unique(studio)),
length(unique(posizio))))
> dimnames(tutti)<-list(studio = c("L.Elem.", "M.Sup.", "Dipl.",
"Laurea"),posizio = c("Operaio", "Impiegato", "Quadro"))
Posizione professionale
Titolo di studio
Operaio
L.Elem.
M.Sup.
Laurea
Impiegato
Dipl.
Figura 3.8: Diagrammi a torta — Esempio 3.1.1
otteniamo la seguente tabella:
90
Quadro
E. D. Isaia, Linguaggio R e applicazioni statistiche
> tutti
posizio
studio
Operaio Impiegato Quadro
L.Elem.
10
1
1
M.Sup.
6
14
1
Dipl.
0
10
3
Laurea
0
1
3
di cui in figura (3.8) riportiamo i diagrammi delle rispettive distribuzioni marginali.
♥
Esempio 3.2.2 Con riferimento alla situazione di cui all’Esempio 3.2.1, ci proponiamo di
individuare le distribuzioni congiunte i frequenze assolute del titolo di studio (studio) e della
posizione professionale (posizio) condizionatamente al sesso.
A tal fine (cfr. Esempio 3.1.4) possiamo ricorrere al comando split(variabile,flag); le
istruzioni:
>
>
>
>
studio.f<-split(matrice[,1],matrice[,3])$"0"
studio.m<-split(matrice[,1],matrice[,3])$"1"
posizio.f<-split(matrice[,2],matrice[,3])$"0"
posizio.m<-split(matrice[,2],matrice[,3])$"1"
ci consentono, infatti, di generare le seguenti due tabelle
> table(studio.m,posizio.m)
posizio.m
studio.m 0 1 2
0 7 1 1
1 2 7 0
2 0 5 1
3 0 0 2
> table(studio.f,posizio.f)
posizio.f
studio.f 0 1 2
0 3 0 0
1 4 7 1
2 0 5 2
3 0 1 1
Anche in questo caso (cfr. Esempio 3.2.1) possiamo migliorare la leggibilità delle tabella
ricorrendo ai comandi array() e dimnames(); tuttavia ci pare utile disporre di una sola lista,
che chiameremo ms.sex, contenente le tabelle in esame sottoforma di matrice. A tal fine:
— creiamo l’oggetto ms.sex i cui elementi sono le frequenze assolute delle distribuzioni
congiunte table(studio.m,posizio.m) e table(studio.m,posizio.m); cioè:
> ms.sex<-c(c(table(studio.m,posizio.m)),c(table(studio.f,posizio.f)))
91
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
— trasformiamo l’oggetto ms.sex in array(), con dimensioni pari al numero delle modalità di ciascuna m.s. considerata, mediante l’istruzione:
> ms.sex<-array(ms.sex,dim=c(length(unique(studio)),
length(unique(posizio)),length(unique(sex)))
— miglioriamo la leggibilità della matrice attribuendo le appropriate etichette alla sue
modalità con il comando:
> dimnames(ms.sex)<-list(studio = c("L.Elem.","M.Sup.","Dipl.",
"Laurea"),posizio = c("Operaio","Impiegato","Quadro"),
sesso =c("Maschi","Femmine"))
In definitiva in ms.sex avremo:
> ms.sex
, , sesso = Maschi
posizio
studio
Operaio Impiegato Quadro
L.Elem.
7
1
1
M.Sup.
2
7
0
Dipl.
0
5
1
Laurea
0
0
2
, , sesso = Femmine
posizio
studio
Operaio Impiegato Quadro
L.Elem.
3
0
0
M.Sup.
4
7
1
Dipl.
0
5
2
Laurea
0
1
1
Osservazione 3.2.1 Desiderando estrarre, per ulteriori elaborazioni, le distribuzioni congiunte condizionate alla mutabile sesso, possiamo ricorrere ai consueti comandi, ricordando
che ms.sex è un array a tre dimensioni; ad esempio:
> ms.sex.maschi<-ms.sex[,,sesso="Maschi"]
> ms.sex.femmine<-ms.sex[,,sesso="Femmine"]
♥
Esempio 3.2.3 Con riferimento alla situazione descritta agli Esempi 3.2.1 e 3.2.2, ci proponiamo ora il calcolo, per ciascuna delle due distribuzioni congiunte presenti in ms.sex, dell’indice di dipendenza globale χ2 del Pearson nonché dell’indice normalizzato V del Cramér,
definiti, con ovvio significato dei simboli:
)
*0.5 )
*0.5
r !
r
!
(nij − n̂2ij )
χ2
χ2
2
χ =
V =
=
inf [n (r − 1); n (s − 1)]
n2ij
M ax(χ2 )
i=1 i=1
92
E. D. Isaia, Linguaggio R e applicazioni statistiche
A tal fine, possiamo creare una funzione ad hoc, di nome ad esempio chi.sqr, che potrà
assumere la forma:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
chi.sqr<-function(x,decimali=4,print.out=TRUE)
{
if (!is.matrix(x)){
stop("X ust be a matrix")}
rig.tot<-apply(x, 1, sum)
col.tot<-apply(x, 2, sum)
tot<-sum(col.tot)
Teor<- outer(rig.tot, col.tot, "*")/sum(x)
Teor.out<-round(Teor,decimali)
C<-round(x-Teor,decimali)
Chi<-round(sum((x-Teor)^2/Teor),decimali)
VCr<-round(Chi/(min(c(tot*(nrow(x)-1),tot*(ncol(x)-1)))),decimali)
if (print.out)
{
cat("X =", Chi, "\n")
cat("V =", VCr, "\n")
}
invisible(list(chi.sq=Chi,V=VCr,teorici=Teor.out,cont=C))
}
A commento:
— input della funzione è un oggetto con struttura di matrice; in caso contrario (riga [3] e
[4]) viene visualizzato un messaggio di errore. Si noti il valore di default attribuito alla
variabile logica print.out;
— i comandi in riga [5], [6] e [7] si calcolano le somme di riga, di colonna nonché la somma
totale;
— il comando outer(rig.tot, col.tot, "*")/sum(x) calcola la matrice delle frequenze
teoriche (Teor);
— le righe [9] e [10] calcolano la matrice delle frequenze teoriche (Teor.out) e la matrice
delle contingenze (C.out) che verranno inserite nella lista dei risultati in uscita;
— le righe [11] e [12] si occupano del calcolo dei due indici richiesti;
— in riga [13] il controllo if (print.out) consente di procedere alla visualizzazione (in
riga [15] e [16]) dei risultati, a patto che print.out=TRUE; in riga [18] si crea, non
visualizzandola, una lista che contiene i due indici richiesti, la matrice delle matrice
delle frequenze teoriche e la matrice delle contingenze.
Osservazione 3.2.2 Si noti che nella funzione chi.sqr proposta non si è fatto ricorso ad
alcun ciclo di calcolo iterativo.
Tornando al problema postoci, abbiamo:
93
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
>
>
>
X
V
>
X
V
x.m<-taglio[,,sesso="Maschi"]
x.f<-taglio[,,sesso="Femmine"]
chi.sqr(x.m)
= 25.2623
= 0.4858
chi.sqr(x.f)
= 12.8407
= 0.2675
Desiderando visualizzare il contenuto della lista in uscita dalla funzione chi.sqr, è sufficiente
digitare print(chi.sqr() o print(chi.sqr(...,print.out=FALSE))). Qualora si desideri
estrarre alcuni risultati per successive elaborazioni si è obbligati ad assegnare l’output di
chi.sqr ad una nuova variabile (di tipo list) e successivamente da questa estrarre gli oggetti
di interesse; ad esempio:
> contingenze.m<-chi.sqr(x.m,print.out=FALSE)$cont
> contingenze.m
posizione
studio
Operaio Impiegato Quadro
L.Elem. 3.8846
-3.5 -0.3846
M.Sup. -1.1154
2.5 -1.3846
Dipl.
-2.0769
2.0 0.0769
Laurea -0.6923
-1.0 1.6923
♥
Esempio 3.2.4 L’archivio stat5.dat contiene il numero, espresso in migliaia di unità, degli occupati totali e suddivisi per sesso in Italia negli anni 1982 − 1990; come di consueto
acquisiamo tali dati mediante le istruzioni:
> esempio5<-read.table(file="stat5.txt")
> names(esempio5)
[1] "tempo"
"maschi" "femmine" "mf"
> attach(esempio5)
Volendo in qualche modo evidenziare l’eventuale diversità della dinamica del fenomeno in
esame, conviene ragionare, più che in valori assoluti, in termini di numeri indice a base fissa.
A tal fine trasformiamo le serie maschi femmine e mf nelle corrsipondenti serie di numeri
indice percentuali, ponendo quale base la situazione dell’anno iniziale, mediante i comandi:
> ind.m<-(maschi/maschi[1])*100
> ind.f<-(femmine/femmine[1])*100
> ind.mf<-(mf/mf[1])*100
In figura (3.9) è evidenziato l’andamento delle tre serie sia in termini di valori assoluti sia in
termini di numeri indici, in base al quale si nota una “esplosione” dell’occupazione femminile.
Per inciso, che il numero degli occupati di sesso femminile è aumentato, nei nove anni
considerati, del 12.7%, mentre quello dei maschi rimasto all’incirca costante; infatti:
94
E. D. Isaia, Linguaggio R e applicazioni statistiche
(b) - Numeri indice (base 1982)
112
25000
(a) - Valori assoluti
Femmine
Maschi
Entrambi
100
5000
102
104
10000
106
15000
108
20000
110
Femmine
Maschi
Entrambi
1982
1984
1986
1988
1990
1982
1984
anni
1986
1988
1990
anni
Figura 3.9: Occupazione italiana nel periodo 1982-1990 — Esempio 3.2.4
> ind.f[length(ind.f)]-100
[1] 12.70693
> ind.m[length(ind.m)]-100
[1] -0.1288568
Procedendo, ci pare corretto adottare, per ciascuna serie di numeri indice, un modello interpolante del tipo ŷi = a0 + a1 ti , con i = 1, 2, . . . , n, dove, ricorrendo al metodo dei minimi
quadrati:
a1 =
Cov(T, Y )
σT2
a0 = µY − a1 µT
Possiamo, dunque, ricorrere3 ai comandi cov(x,y) e var(x):
> n<-length(tempo)
> a1<-cov(ind.m,tempo)*((n-1)/n)/var(tempo)*((n-1)/n)
> a0<-mean(ind.m)-a1*mean(tempo)
> a0
[1] 208.1988
> a1
[1] -0.05458331
3
Si rammenta che, come nel caso del calcolo della varianza (cfr Osservazione??), la covarianza tra
due o più v.s. viene calcolata ponendo a denominatore n − 1 in luogo di n.
95
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
sı̀ che il modello interpolante a minimi quadrati risulta Maschi ŷi = 208.1988 − 0.0546 ti.
Operando in modo analogo per le altre serie di numeri indici otteniamo:
F emmine ŷi
= −2771.763 + 1.4488 ti
F emmine+Maschi ŷi
= −740.4797 + 0.4240 ti
I valori teorici in base ai modelli sono stati raccolti nel vettori modello.m, modello.f e
modello.mf ottenuti mediante le semplici istruzioni:
>
>
>
>
>
>
>
>
>
a1<-cov(ind.m,tempo)*((n-1)/n)/var(tempo)*((n-1)/n)
a0<-mean(ind.m)-a1*mean(tempo)
modello.m<-a0+a1*tempo
a1<-cov(ind.f,tempo)*((n-1)/n)/var(tempo)*((n-1)/n)
a0<-mean(ind.f)-a1*mean(tempo)
modello.f<-a0+a1*tempo
a1<-cov(ind.mf,tempo)*((n-1)/n)/var(tempo)*((n-1)/n)
a0<-mean(ind.mf)-a1*mean(tempo)
modello.mf<-a0+a1*tempo
Per completezza, in figura (3.10) è riportato l’andamento delle tre rette interpolanti.
Osservazione 3.2.3 I passi necessari ai fini della costruzione del grafico proposto in figura
(3.10) sono stati:
— introduzione della variabile yrange che definisce il campo di variazione (a, b) dei valori
in ordinata:
>
>
>
>
a<-min(min(ind.f),min(ind.m),min(ind.mf))
b<-max(max(ind.f),max(ind.m),max(ind.mf))
yrange<-c(a,b)
rm(a,b)
— costruzione del grafico di base “vuoto” (opzione type="n") con suddivisione (opzione
ylim=) dell’asse delle ordinate in accordo ai valori posti in yrange, munito di titolo
(opzione main=) e etichette per l’asse delle ascisse (opzione xlab=) e quello delle ordinate
(opzione ylab=):
> plot(tempo,modello.m,,type="n",ylim=yrange,
xlab="anni",ylab="",main="(b) - Numeri indice (base 1982)")
— rappresentazione delle coppie di punti (Ŷ , t) con i comandi:
> points(tempo,modello.m,col="red")
> points(tempo,modello.f,col="black")
> points(tempo,modello.mf,col="blue")
96
E. D. Isaia, Linguaggio R e applicazioni statistiche
(b) - Numeri indice (base 1982)
100
102
104
106
108
110
112
Femmine
Maschi
Femmine+Maschi
1982
1984
1986
1988
1990
anni
Figura 3.10: Occupazione italiana nel periodo 1982-1990 — Esempio 3.2.4
— rappresentazione delle tre rette interpolanti ricorrendo alla funzione lines(x,y); per
migliorarne la leggibilità impieghiamo altrettanti tipi di tratteggio (opzione lty=). I
comandi impartiti sono:
> lines(tempo,modello.m,col="red",lty=3)
> lines(tempo,modello.f,,col="black",lty=1)
> lines(tempo,modello.mf,,col="blue",lty=5)
— introduzione della variabile testo, contenente il testo della legenda, e visualizzazione
della legenda stessa a partire dai punti di coordinate indicati in coord.leg:
> coord.leg<-c(min(tempo),max(ind.f))
> testo<-c("Femmine","Maschi","Femmine+Maschi")
> legend(coord.leg,legend=testo,col=seq(testo),lty = c(1,3,5))
È superfluo osservare che la maggior parte dei comandi presentati potrebbere essere inserita
in una funzione ad hoc, sı̀ da automatizzare le procedure.
♥
97
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Esempio 3.2.5 Con riferimento alle due variabili contenute in stat6.dat, che acquisiamo
mediante i consueti comandi:
> esempio6<-read.table(file="stat6.txt")
> names(esempio6)
[1] "mate" "stat"
> attach(esempio6)
può essere interessante evidenziare ed analizzare l’eventuale legame di dipendenza tra le v.s.
Y =voto conseguito in Statistica e X =voto di ottenuto in Matematica.
A tal fine, iniziamo con la presentazione della distribuzione congiunta delle v.s. in esame, che,
come di consueto, otteniamo ricorrendo al comando table(); pertanto:
> table(mate,stat)
stat
mate 18 19 20 21 22 23 25 26 27 29 30
18 2 0 1 0 0 0 0 0 0 0 0
19 0 0 1 1 0 1 0 0 0 0 0
20 0 1 3 0 0 1 0 0 0 0 0
21 0 0 0 1 1 1 0 0 0 0 0
23 0 0 1 1 0 1 2 0 0 0 0
25 0 0 1 0 0 0 2 0 1 0 0
26 0 0 0 0 0 0 1 0 4 0 0
27 0 0 0 0 0 0 0 1 3 0 1
28 0 0 0 0 0 0 0 0 1 1 1
30 0 0 0 0 0 0 0 0 0 1 3
È sufficiente una rapida lettura della tabella per accorgersi di una dipendenza (in senso
statistico) tra le variabili oggetto di studio. A tal proposito4 :
> chi.sqr(table(mate,stat))
X = 129.637
V = 0.3601
Anzi, la circostanza che buona parte delle frequenze osservate giaccia sulla diagonale principale
può indurci a ritenere il legame di dipendenza positivo e di tipo, approssimativamente, lineare.
Per sincerarsene, possiamo costruire un semplice diagramma a dispersione tra le variabili
originarie mate e stat oppure ricorrere ad un diagramma a dispersione dei voti medi di
Statistica condizionati a ciascun voto riportato in Matematica.
Prima di presentare i risultati, occupiamoci del calcolo delle medie della v.s. condizionata Y |X, in simboli µY |X=xi . A tale scopo, ricorriamo alla ormai nota funzione split() e
successivamente al nuovo comando5 sapply(). In particolare:
4
Si tratta dell funzione presentata all’Esempio 3.2.3.
Il cui comportamento è simile a quello dei comandi apply() e tapply(). Argomenti sonol’oggetto
su cui operare e la funzione che si desidera applicare.
5
98
E. D. Isaia, Linguaggio R e applicazioni statistiche
— definiamo l’oggetto stat.m che conterrà, sottoforma di lista, i voti di Statistica in
corrispondenza a ciascuna modalità (o livello) del voto di Matematica;
#&
#%
##
!"
#$
,()*+,10-+,-+,3*/*+4*+2/
#"
'$
— calcoliamo le medie di ciascun oggetto contenuto in stat.m, cioè le medie condizionate µY |X=xi , con il comando sapply(stat.m,mean); i risultati, utili per successive
elaborazioni, verranno inseriti nel nuovo oggetto medie.cond.
!"
#$
##
#%
#&
#"
'$
()*+,-+,./*01/*+2/
Figura 3.11: Medie condizionate e spezzata di regressione — Esempio 3.2.5
Ciò premesso, le istruzioni6 :
> stat.m<-split(stat, mate)
> media.cond<-round(sapply(stat.m, mean),4)
In definitiva le medie condizionate µY |X=xi , espresse a solo due decimali, risultano:
> round(media.cond,2)
18
19
20
21
23
25
26
27
28
30
18.67 21.33 20.40 22.00 22.80 24.25 26.60 27.40 28.67 29.75
A questo punto possiamo procedere alla costruzione di un diagramma a dispersione dove
rappresenteremo le coppie (xi , µY |X=xi ); le istruzioni:
6
Sarebbe sufficiente la sola istruzione: medie.cond<-sapply(split(stat, mate), mean).
99
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> plot(unique(sort(mate)),media.cond,type="p",cex=2.5,pch=20,col="red",
frame.plot=FALSE,ann=FALSE,cex.main=1,font.main=1,ylim=c(18,30))
> lines(unique(sort(mate)),media.cond,col="blue")
> title(main="",xlab="Voti di Matematica",ylab=" Voti medi di Statistica")
porgono il grafico riportato in figura (3.11).
A questo punto, evidenziata l’esistenza, perlomeno graficamente, di un legame lineare tra
le variabili considerate possiamo “quantizzarla”. Innanzitutto possiamo procedere al calcolo
del coeficiente di correlazione lineare del Pearson (ρ) che “a occhio” dovrà risultare prossimo
all’unità7 ; infatti abbiamo:
#&
#%
##
!"
#$
,()*+,10-+,-+,3*/*+4*+2/
#"
'$
> (rho<-cor(stat,mate))
[1] 0.9052952
!"
#$
##
#%
#&
#"
'$
()*+,-+,./*01/*+2/
Figura 3.12: Retta di regressione — Esempio 3.2.5
7
Nel caso di adozione di un modello lineare esso viene a coincidere, com’è noto, con il coefficiente
di determinazione.
100
E. D. Isaia, Linguaggio R e applicazioni statistiche
Inoltre possiamo individuare i parametri della retta di regressione yi = a0 + a1 xi . Ricordando
che:
a1 =
σY
Cov(X, Y )
=ρ
2
σX
σX
a0 = µY − a1 µX
le istruzioni:
> a1<-rho*sqrt(var(stat))/sqrt(var(mate))
> a0<-mean(stat)-a1*mean(mate)
> modello<-a0+a1*mate
porgono:
> a1
[1] 0.9078971
> a0
[1] 2.605864
sı̀ che la retta di regressione viene ad assumere la forma yi = 2.6059 + 0.9079 xi , il cui
andamento è riportato in figura (3.12), ottenuto mediante le istruzioni:
> plot(unique(sort(mate)),media.cond,type="p",cex=2.5,pch=20,col="red",
frame.plot=FALSE,ann=FALSE,cex.main=1,font.main=1,ylim=c(18,30))
lines(mate,modello,col="blue")
♥
Esempio 3.2.6 Si immagini di avere rilevato, su gruppo di n = 10 autovetture europee
medio-piccole ad alimentazione a benzina, la cilindrata (x1 ), la potenza espressa in CV-Din
(x2 ), la velocità massima dichiarata (x3 ) ed il consumo di carburante (x4 ), ottenendo i risultati
che seguono:
x1
x2
x3
x4
1100
45
135
5
1200
54
145
5.5
1000
45
140
4.8
1300
50
140
6.2
1400
60
150
6.7
1000
45
140
5
1100
50
140
4.8
1200
54
145
5.2
1400
70
165
6.7
1250
60
155
6.2
Definito8 il data frame auto, contenente tutte le informazioni:
>
>
>
>
x1<-cbind(c(11, 12, 10, 13, 14, 10, 11, 12, 14, 12)*100)
x2<-cbind(c(45, 54, 45, 50, 60, 45, 50, 54, 70, 60))
x3<-cbind(c(135, 145, 140, 140, 150, 140, 140, 145, 165, 155))
x4<-cbind(c(5, 5.5, 4.8, 6.2, 6.7, 5, 4.8, 5.2, 6.7, 6.2))
8
Meno elegantemente avremmo potuto definire la matrice X<-cbind(x1,x2,x3,x4) ed operare su
di essa attribuendo nomi appropriati ai suoi vettori colonna.
101
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> (auto<-data.frame(Cilindrata=x1,CV.Din=x2,Vel.max=x3,Consumo=x4))
Cilindrata CV.Din Vel.max Consumo
1
1100
45
135
5.0
2
1200
54
145
5.5
3
1000
45
140
4.8
4
1300
50
140
6.2
5
1400
60
150
6.7
6
1000
45
140
5.0
7
1100
50
140
4.8
8
1200
54
145
5.2
9
1400
70
165
6.7
10
1200
60
155
6.2
calcoliamo la matrice dei coefficienti di correlazione lineare tramite il semplice comando 9 :
> round(cor(auto),4)
Cilindrata
Cilindrata
1.0000
CV.Din
0.8305
Vel.max
0.6889
Consumo
0.9194
CV.Din Vel.max Consumo
0.8305 0.6889 0.9194
1.0000 0.9637 0.8282
0.9637 1.0000 0.7661
0.8282 0.7661 1.0000
Per avere un’idea “globale” delle relazioni tra le variabili conteute in auto, possiamo pensare di
creare i diagrammi a dispersione tra tutte le 42 − 4 = 12 combinazioni delle variabili oggetto
di studio. Ciò può essere attuato ricorrendo alla funzione pairs(). Tuttavia desiderando
migliorare la situazione di default, scegliamo di:
— rappresentare sulla diagonale principale gli istogrammi delle variabili x1,x2,x3 e x4; a
tal fine ricorriamo alla funzione panel.hist presentata in 2.1.12;
— visualizzare, nelle celle a destra della diagonale principale, i diversi coefficienti di correlazione lineare; a tal fine consideriamo la nuova funzione:
panel.cor <- function(x, y, digits=2,pch=20)
{
par(usr = c(0, 1, 0, 1))
r <- cor(x, y)
txt <- paste(format(r, digits=digits),sep="")
text(0.5, 0.5, txt, cex = 2)
}
A questo punto il comando:
> pairs(auto,pch = 20,diag.panel=panel.hist,upper.panel=panel.cor)
9
Si osservi che stiamo operando sull’intero data frame e non sui suoi singoli componenti, per il
momento non disponibili (cfr. paragrafo 1.4.2).
102
E. D. Isaia, Linguaggio R e applicazioni statistiche
5.0
5.5
6.0
6.5
Cilindrata
0.69
0.92
0.96
0.83
1000
0.83
1200
1400
45 50 55 60 65 70
6.5
135
0.77
145
Vel. max.
155
165
45
55
65
CV-Din
5.0
5.5
6.0
Consumo
1000
1200
1400
135
145
155
165
Figura 3.13: Matrice dei diagrammi a dispersione — Esempio 3.2.6
porge il grafico riportato in figura (3.13). Lasciamo al Lettore la verifica sul campo del
comando:
> pairs(auto,pch = 20,diag.panel=panel.hist,lower.panel=panel.cor)
♥
Esempio 3.2.7 A volte capita, nel caso di analisi di una variabile statistica doppia, di disporre non già dei singoli dati individuali, bensı̀ degli stessi raccolti in distribuzione congiunta
di frequenze. In tali situazioni è sempre possibile procedere ad analisi statistiche dei dati in
R, purché questi vengano acquisiti in modo corretto.
Distinguiamo i casi:
— abbiamo a disposizione una tabella a doppia entrata per due caratteri qualitativi, ad
esempio:
103
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
m.s. B →
m.s. A ↓
a1
a2
a3
b1
b2
200
400
100
150
100
250
I dati potranno essere correttamente acquisiti in R tramite le istruzioni:
> ms.AB<-array(c(200,400,100,150,100,250),dim=c(3,2))
> dimnames(ms.AB)<-list(A = c("a1", "a2", "a3"),B = c("b1", "b2"))
infatti:
> ms.AB
B
A
b1 b2
a1 200 150
a2 400 100
a3 100 250
— abbiamo a disposizione una tabella a doppia entrata per due caratteri quantitativi, ad
esempio:
v.s. Y →
v.s. X ↓
0
1
0
1
10
30
20
10
I dati potranno essere correttamente acuisiti in R tramite le istruzioni:
> vs.XY<-array(c(10,30,20,10),dim=c(2,2))
> vs.XY
> vs.XY
Y
X
0 1
0 10 20
1 30 10
e, per ulteriori elaborazioni:
> XY<-array(c(0,0,1,1,0,1,0,1,10,20,30,10),dim=c(4,3))
> XY
[,1] [,2] [,3]
[1,]
0
0
10
[2,]
0
1
20
[3,]
1
0
30
[4,]
1
1
10
104
E. D. Isaia, Linguaggio R e applicazioni statistiche
♥
Esempio 3.2.8 Se un oggetto contiene valori mancanti (NA) l’applicazione delle funzioni
statistiche standard elencate, ad esempio, in (3.1.3) comporta alcuni problemi poiché essi, per
default, vengono conteggiati in length(oggetto). In effetti le funzioni in questione tengono
conto della possiblità di escludere i valori mancanti; ad esempio la funzione mean è definita:
1
2
3
4
5
6
mean<-function (x,na.rm = FALSE)
{
if(na.rm) {x <- x[!is.na(x)]}
else if(any(is.na(x))) {return(NA)}
sum(x)/length(x)
}
sicché è sufficiente modificare la situazione di default na.rm = FALSE in na.rm = TRUE. Ad
esempio:
> x<-c(NA,12,NA,14,15,17,21)
> x
[1] NA 12 NA 14 15 17 21
> mean(x)
[1] NA
> mean(x,na.rm=TRUE)
[1] 15.8
Nel seguito proponiamo due semplici alternative che a nostro avviso consentono un maggior
controllo dei valori mancanti.
Le funzioni off.na(x) e rep.na(x) consentono di modificare un oggetto che presenta elementi
mancanti (NA). La prima funzione si limita ad eliminarli, mentre la seconda sostituisce tali
valori con il valor medio o, a discrezione dell’utente, con la mediana di x. Per comodità i
nuovi valori in uscita sono messi negli oggetti w.off e w.rep rispettivamente. I listati delle
due funzioni sono:
1
2
3
4
5
off.na<-function(x)
{
w.off<<-x[!is.na(x)]
cat("The new w.off object has been created","\n")
}
Cosı̀ ad esempio:
> x<-c(NA,12,NA,14,15,17,21)
> x
[1] NA 12 NA 14 15 17 21
> off.na(x)
The new w.off object has been created
105
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> w.off
[1] 12 14 15 17 21
> mean(w.off)
[1] 15.8
1
2
3
4
5
6
7
8
9
10
11
rep.na<-function(x, media=TRUE)
{
if (!media){valore<-median(x[!is.na(x)])}
else {valore<-mean(x[!is.na(x)])}
for (i in (1:length(x)))
{
if (is.na(x[i])==TRUE) {x[i]<-valore}
}
w.rep<<-x
cat("The new w.rep object has been created","\n")
}
> rep.na(x)
The new w.rep object has been created
> w.rep
[1] 15.8 12.0 15.8 14.0 15.0 17.0 21.0
> rep.na(x,media=FALSE)
The new w.rep object has been created
> w.rep
[1] 15 12 15 14 15 17 21
♥
106
Capitolo 4
Elementi di calcolo delle probabilità
In ambiente R sono implementate le principali distribuzioni di probabilità univariate.
Esse sono identificate da un nome proprio che deve obbligatoriamente essere preceduto
da un suffisso che indica quale aspetto di esse si desidera, ed infine dalla lista dei
parametri che contraddistinguono ciascuna v.c..
Quanto ai suffissi, comuni a tutte le v.c.:
— d porge i valori della densità in corrispondenza ai valori specificati in x;
— p porge i valori della funzione di ripartizione in corrispondenza ai valori indicati
in x;
— q porge i valori dei quantili in corrispondenza ai valori elencati in prob;
— r estrae casualmente noss elementi dalla densità specificata;
Quanto alle distribuzioni di probabilità implementate, citiamo:
! binomiale
f (x) =
2
n
x
3
px (1 − p)n−x
dbinom(x,n, p)
qbinom(prob, n, p)
pbinom(x, n, p)
rbinom(noss, n, p)
! binomiale negativa
f (x) =
2
x+r−1
x
dnbinom(x, r, p)
qnbinom(prob, r, p)
3
pr (1 − p)x
pnbinom(x, r, p)
rnbinom(noss, r, p)
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
! geometrica
f (x) = p(1 − p)x
dgeom(x, p)
qgeom(prob, p)
pgeom(x, p)
rgeom(noss, p)
! ipergeometrica
f (x) =
2
32
N1
N2
x
n−x
2
3
N1 + N2
n
dhyper(x, N1, N2)
qhyper(prob, N1, N2)
3
phyper(x, N1, N2)
rhyper(noss, N1, N2)
! di Poisson
f (x) =
λx e−λ
x!
dpois(x, lambda)
qpois(prob, lambda)
ppois(x, lambda)
rpois(noss, lambda)
! Chi-Quadro
f (x) =
1
2
n/2
dchisq(x, df)
qchisq(prob, df)
Γ (n/2)
xn/2−1 e−x/2
pchisq(x, df)
rchisq(noss, df)
! esponenziale
f (x) = λe−λx
dexp(x, rate)
qexp(prob, rate)
pexp(x, rate)
rexp(noss, rate)
! F di Snedecor
f (x) =
Γ (n1 /2 + n2 /2) n1 n1 n1 /2−1
n1 x −(n1 +n2 )/2
( )2x
(1 +
)
Γ (n1 /2) Γ (n2 /2) n2
n2
df(x, n1, n2)
qf(prob, n1, n2)
pf(x, n1, n2)
rf(noss, n1, n2)
108
E. D. Isaia, Linguaggio R e applicazioni statistiche
! gamma
f (x) =
1
xa−1 e−x/b
b Γ (a)
a
dgamma(x, shape, scale)
qgamma(prob, shape, scale)
pgamma(x, shape, scale)
rgamma(noss, shape, scale)
! normale
1
2
f (x) = √ e−(x−µ)/2σ
σ 2π
dnorm(x, mean, sd)
qnorm(prob, mean, sd)
pnorm(x, mean, sd)
rnorm(noss, mean, sd)
! t di Student
f (x) =
dt(x, df)
qt(prob, df)
5 6−(n+1)/2
Γ (n + 1/2) 4
√
1 + x2 2
Γ (n/2) nπ
pt(x, df)
rlt(noss, df)
! uniforme
f (x) =
1
max − min
dunif(x, min, max)
qunif(prob, min, max)
punif(x, min, max)
runif(noss, min, max)
Osservazione 4.0.4 La v.c. Chi-Quadro precedentemente introdotta non è altro che
un particolare caso della distribuzione Chi-Quadro non centrale. Questa rappresenta
la distribuzione della somma dei quadrati di n v.c. indipendenti e normalmente
distribuite ciascuna con varianza unitaria e valor medio µ i , i = 1, 2, . . . , n. La densità
di una v.c. Chi-Quadro non centrale con ν gradi di libertà e parametro di non
(
centralità λ = ni=1 µ2 , per x ≥ 0, è:
fnc (x) = e(−λ/2)
+∞
!
(λ/2)r
f (x; ν + 2 r)
r!
r=0
dove f (x) indica la densità di una v.c. Chi-Quadro con ν + 2 r gradi di libertà.
Per una v.c. Chi-Quadro con parametro di non centralità λ =ncp, si ha:
109
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
dchisq(x, df, ncp=0)
qchisq(prob, df, ncp=0)
pchisq(x, df, ncp=0)
rchisq(noss, df, ncp=0)
A tal proposito, osserviamo ancora la possibilità di calcolare particolari valori di
interesse della funzione di ripartizione delle distribuzioni F di Snedecor e t di Student con parametro di non centralità ncp tramite i comandi pf(t, df =,ncp=) e
pt(t, df =, ncp=)
4.1
Semplici esercizi sul calcolo delle probabilità
Nel seguito i limitiamo a fornire alcuni semplici esempi applicativi che coinvolgono in
modo diretto le v.c. introdotte al paragrafo precedente.
Esempio 4.1.1 Visualizzare la funzione di distribuzione di probabilità e la funzione di ripartizione di una v.c. binomiale di parametri n = 9, p = 0.5; le istruzioni possono essere:
>
>
>
>
x<-c(0:9)
par(mfrow=c(1, 2))
plot(x,pbinom(x,9,.5),col="red",type="s",ann=FALSE)
title(main="(a) - Funzione di ripartizione",
xlab="Determinazioni x",ylab="P(Xx)")
> plot(x,dbinom(x,9,.5),col="blue",type="h",ann=FALSE)
> title(main="(b) - Distribuzione di probabilita’",
xlab="Determinazioni x",ylab="P(X=x)")
> par(mfrow=c(1, 1))
il cui output è riprodotto in figura (4.1).
♥
Esempio 4.1.2 Ci proponiamo di visualizzare la funzione di ripartizione di una v.c. con
distribuzione binomiale di parametri n = 9 e p = 0.10, 0.25, 0.50, 0.75, 0.90; le istruzioni
possono essere:
>
>
>
>
>
>
>
>
>
x<-c(0:9)
plot(x,pbinom(x,9,.5),xlim=c(-1,10),type="n",ann=FALSE)
title(main="",xlab="Numero di prove",ylab="P[X x]")
for(p in c(0.10,0.25,0.50,0.75,0.90))
{lines(x,pbinom(x,9,p),col=p*10,type="s")}
text(0.65,0.80,"p=0.10",cex=.75)
text(1.70,0.65,"p=0.25",cex=.75)
text(3.25,0.30,"p=0.50",cex=.75)
text(5.25,0.20,"p=0.75",cex=.75)
text(6.20,0.10,"p=0.90",cex=.75)
il cui output è riprodotto in figura (4.2).
110
E. D. Isaia, Linguaggio R e applicazioni statistiche
(b) - Distribuzione di probabilita'
0.15
0.05
0.10
P(X=x)
0.6
0.4
0.0
0.00
0.2
P(X!x)
0.8
0.20
1.0
0.25
(a) - Funzione di ripartizione
0
2
4
6
8
0
Determinazioni x
2
4
6
8
Determinazioni x
Figura 4.1: Distribuzione binomiale, n=9 e p=0.5 — Esempio 4.1.1
Esempio 4.1.3 Calcolare la probabilità all’evento {5 ≤ X ≤ 7}, posto che X sia una v.c.
binomiale con parametri n = 10, p = 0.75; le istruzioni possono essere:
> pbinom(7,10,.75)-pbinom(5,10,.75)
[1] 0.3962803
Tutto ciò è piuttosto ripetitivo; la seguente funzione, in base ai parametri essenziali, porge la
soluzione desiderata:
1
> evento<-function(x1,x2,n,p){print(pbinom(x2,n,p)-pbinom(x1,n,p))}
A questo punto l’istruzione evento(5,7,10,.75) restutuisce il risultato desiderato.
♥
Esempio 4.1.4 Calcolare i percentili di ordine 5, 15, ..., 85, 95 di una distribuzione ChiQuadro con 10 gradi di libertà.
A tal fine è sufficiente impartire l’istruzione:
> qchisq(ppoints(10), 10)
[1] 3.940299 5.570059 6.737201 7.783243 8.812352
[6] 9.892216 11.097142 12.548861 14.533936 18.307038
111
p=0.10
0.6
p=0.25
0.4
P[X ! x]
0.8
1.0
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
0.2
p=0.50
p=0.75
0.0
p=0.90
0
2
4
6
8
10
Numero di prove
♥
Figura 4.2: Funzioni di ripartizione di v.c. Bin(n = 9, p) — Esempio 4.1.2
♥
2
Esempio 4.1.5 Posto X una v.c. N (µX = 120, σX
= 25), calcolare la probabilità attinente
agli eventi {X ≥ (µX − σX )} e {(µX − σX ) ≤ X ≤ (µX + σX )}.
Sono sufficienti le istruzioni:
> mu<-120 : s<-5
> 1-pnorm(115,mu,s)
[1] 0.8413447
> pnorm(125,mu,s)-pnorm(115,mu,s)
[1] 0.6826895
♥
Esempio 4.1.6 Posto X una v.c. N (0, 1), calcolare la probabilità attinente all’evento {X ≥
x}, con x = 0, 3, (0.05).
Si tratta di calcolare le probabilità della coda destra di una N (0, 1) in corrispondenza a
determinati quantili; il problema viene risolto mediante le istruzioni:
112
E. D. Isaia, Linguaggio R e applicazioni statistiche
> x<-seq(0,3,by=0.05)
> n.prob.coda.dx<-1-pnorm(x,0,1)
> round(n.prob.coda.dx,4)
[1] 0.5000 0.4801 0.4602 0.4404
[10] 0.3264 0.3085 0.2912 0.2743
[19] 0.1841 0.1711 0.1587 0.1469
[28] 0.0885 0.0808 0.0735 0.0668
[37] 0.0359 0.0322 0.0287 0.0256
[46] 0.0122 0.0107 0.0094 0.0082
[55] 0.0035 0.0030 0.0026 0.0022
0.4207
0.2578
0.1357
0.0606
0.0228
0.0071
0.0019
0.4013
0.2420
0.1251
0.0548
0.0202
0.0062
0.0016
0.3821
0.2266
0.1151
0.0495
0.0179
0.0054
0.0013
0.3632
0.2119
0.1056
0.0446
0.0158
0.0047
0.3446
0.1977
0.0968
0.0401
0.0139
0.0040
Si osservi che coerentemente:
> (n.quantili<-(qnorm(1-n.prob.coda.dx,0,1)))
[1] 0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40
[14] 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05
[27] 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70
[40] 1.95 2.00 2.05 2.10 2.15 2.20 2.25 2.30 2.35
[53] 2.60 2.65 2.70 2.75 2.80 2.85 2.90 2.95 3.00
0.45
1.10
1.75
2.40
0.50
1.15
1.80
2.45
0.55
1.20
1.85
2.50
0.60
1.25
1.90
2.55
♥
Esempio 4.1.7 Per una v.c. N (0, 1) si ha P [X > 1.959964 = x∗ ] = 0.025. Ci proponiamo
di calcolare il corrispondente quantile x∗ per una v.c. con distribuzione t di Student con
gdl = 5, 200, (5) gradi di libertà.
Rsiolviamo il problema ricorrendo alle istruzioni:
>
>
>
>
prob<-0.025
gdl<-seq(5,200,by=5)
quantile.t<-qt(1-prob,gdl)
round(quantile.t,4)
[1] 2.5706 2.2281 2.1314 2.0860
[10] 2.0086 2.0040 2.0003 1.9971
[19] 1.9853 1.9840 1.9828 1.9818
[28] 1.9771 1.9765 1.9759 1.9754
[37] 1.9729 1.9725 1.9722 1.9719
2.0595
1.9944
1.9808
1.9749
2.0423
1.9921
1.9799
1.9744
2.0301
1.9901
1.9791
1.9740
2.0211
1.9883
1.9784
1.9736
2.0141
1.9867
1.9777
1.9732
♥
Esempio 4.1.8 Data una v.c. Gamma(10, 5), il quantile di ordine, poniamo, 0.67 viene ottenuto in modo diretto tramite il comando qgamma(0.67,10,5). Un’alternativa è rappresentata
dal ricorso (cfr. paragrafo ??) alla funzione uniroot(); infatti:
> uniroot(function(x) pgamma(x ,10, 5) - 0.67, c(0, 100))$root
[1] 55.48862
> qgamma(0.67 ,10, 5)
[1] 55.48862
♥
113
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
4.2
Generazione di numeri pseudo-casuali
La generazione di realizzazioni di variabili casuali 1 ha diverse motivazioni, ad esempio
in ambito statistico può essere utilizzata al fine della verifica di modelli teorici o
dell’applicazione di metodi di simulazione quali Monte Carlo ed analoghi.
Le v.c. possono essere generate a partire da numeri casuali o, meglio, dovremmo
dire numeri pseudo-casuali dal momento che la loro generazione avviene in accordo a
specifici algoritmi numerici. La generazione di un numero casuale può essere intesa
come la generazione di un’osservazione da una v.c. con distribuzione uniforme in
(0, 1). Dal momento che la funzione di ripartizione F (·) di qualsiasi v.c. X assume
valori in (0, 1), se generiamo un numero, sia esso w, tra 0 e 1, esisterà smpre un valore
x tale che x = F −1 (w), ovvero tale che w = F (x). In generale è assai complesso
individuare l’inversa di F (·).
A titolo di esempio, si immagini di voler generare una v.c. distribuzione Bernoulliana
di parametro p, ovvero:
X=
+
0 1−p
1 p
con funzione di ripartizione:
F (x) =

0
x<0
1 0≤x<1

1 x≥1
Iniziamo generando un numero w da una v.c. uniforme in (0, 1); se w < 1−p possiamo
definire F −1 (w) = 0, mentre se w ≥ 1 − p definiamo F −1 (w) = 1. In altri termini,
per generare una v.c. di Bernoulli di parametro p è sufficiente generare un numero
compreso tra 0 e 1 e se risulta più piccolo di 1 − p diciamo che X = 0 altrimenti 1.
Dal momento che la condizione w < 1− p è equivalente, in probabilità, alla condizione
w > p, diremo che X = 0 se w > p.
Esempio 4.2.1 Generazione di 5 realizzazioni di una v.c. con distribuzione Bernoulliana di parametro p = 0.25. Estraiamo dapprima cinque numeri da un’uniforme in (0, 1) e
verifichiamo se sono minori di p:
> (w<-runif(5))
[1] 0.29534834 0.21283447 0.26371730 0.93382201 0.07352568
> (esito<-(w<.25)
[1] FALSE TRUE FALSE FALSE TRUE
Trasformiamo, ora, gli elementi del vettore logico esito in un vettore numerico binario:
1
Alternativamente: generazione di numeri casuali
114
E. D. Isaia, Linguaggio R e applicazioni statistiche
> (binario<-1*esito)
[1] 0 1 0 0 1
♥
Come già si disse in (4), in R sono implementate funzioni basate su algoritmi ottimizzati per la generazione di numeri pseudo-cauali. A commento valgano gli esempi che
seguono.
2
Esempio 4.2.2 Generazione di n = 10 numeri casuali tratti da una N (µX = 200, σX
= 225):
> rnorm(10,200,(225)^.5)
[1] 210.0311 198.6509 216.4558 203.8878 199.0929 190.8120 199.3914
[8] 188.4484 201.6433 203.5893
♥
Esempio 4.2.3 Desiderando verificare, perlomeno graficamente, se n osservazioni campionarie possono considerarsi tratte da una distribuzione normale si può ricorrere ad un diagramma
a dispersione avendo cura di porre in ascissa i quantili di una N (µ, σ) ed in ordinata i quantili
campionari (o empirici) calcolati sulla base della n-pla osservata.
Tenendo a mente quanto detto a tal proposito al paragrafo 2.1.5, ciò può essere ottenuto
ricorrendo al comando qqplot(x,y), dove x contiene le osservazioni campionarie e y è definito
come qnorm(ppoints(length(x)),mean(x),sd(x)), oppure tramite il comando qqnorm(x).
A titolo di esempio la figura (4.3) riporta i diagrammi a dispersione dei quantili di sei campioni
tratti da una N (120, 20) di numerosità n = 25, (25), 150, in accordo alle seguenti istruzioni:
> par(mfrow=c(2,3))
> for(n in c(25,50,75,100,125,150))
{
.Random.seed<-c(1,2037680562,1033614556)
qqnorm(rnorm(n),main=paste("n=",n),xlab="Quantili teorici N(0,1)",
ylab=" Quantili campionari",pch=20,col=1+n)
}
> par(mfrow=c(1,1))
Si noti la presenza del comando .Random.seed<-c(1,2037680562,1033614556) che consente
di rigenerare una stessa sequenza di numeri casuali; a tal proposito valga l’Osservazione 4.2.1.
♥
Esempio 4.2.4 La generazione di n = 1000 numeri casuali da una v.c. con distribuzione
Chi-quadro con gdl = 12 gradi di libertà può avvenire tramite il semplice comando:
> valori.chi<-rchisq(1000,12)
115
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
n= 50
n= 75
1
0
Quantili campionari
-1
0
-1
Quantili campionari
1
0
0
1
2
-2
-1
0
1
2
-2
Quantili teorici N(0,1)
n= 125
1
2
2
1
Quantili campionari
1
0
-2
-2
-2
-1
Quantili campionari
2
1
0
Quantili campionari
-1
0
n= 150
2
n= 100
-1
Quantili teorici N(0,1)
0
-1
Quantili teorici N(0,1)
-1
-2
-2
-2
-1
Quantili campionari
1
2
2
n= 25
-2
-1
0
1
Quantili teorici N(0,1)
2
-2
-1
0
1
Quantili teorici N(0,1)
2
-2
-1
0
1
2
Quantili teorici N(0,1)
Figura 4.3: Campionamento da una v.c. N(0, 1): QQ-plot — Esempio 4.2.3
In figura (4.4) è riportato l’istogramma della variabile valori.chi generata nonché il diagramma a dispersione tra i quantili empirici e quelli teorici di una distribuzione N (0, 1); i
grafici proposti sono stati generati dalle istruzioni:
> hist(valori.chi,main="",xlab="x",ylab="Frequenze assolute",
col="lightgreen")
> qqnorm(valori.chi,main="",xlab="Quantili teorici N(0,1)",
ylab=" Quantili campionari",pch=20,col="magenta")
Lasciamo al Lettore l’interpretazione, in termini grafici, dei risultati ottenuti.
♥
Osservazione 4.2.1 A volte può tornare utile rigenerare una stessa sequenza di numeri casuali. A tal fine occerre conoscere e reimmettere il seme che ha generato la
prima sequenza e che è immaganizzato nella variabile .Random.seed. Un modo per
risolvere il problema è il ricorso alle seguenti istruzioni:
> rbinom(5,4,.36)
[1] 1 1 0 1 1
116
25
20
15
0
5
10
Quantili campionari
300
200
100
Frequenze assolute
30
E. D. Isaia, Linguaggio R e applicazioni statistiche
0
5
10
20
30
-3
x
-2
-1
0
1
2
3
Quantili teorici N(0,1)
Figura 4.4: Istogramma e QQ-plot — Esempio 4.2.3
> seme<-.Random.seed
> seme
[1]
1 14739194 782820522
> .Random.seed<-seme
> rbinom(5,4,.36)
[1] 1 1 0 1 1
Per approfondimenti, si vedano gli articoli di Marsaglia (1997) e Wichmann, Hill
(1982) e la bibliografia ivi citata.
4.3
Il campionamento
In R è definita una particolare funzione che consente l’estrazione di un campione
casuale, di dimensione specificata, da un dato oggetto; tale estrazione può avvenire
con o senza rimessa a seconda delle esigenze dell’utente.
La sintassi estesa del comando necessario per accedere a tale funzione è:
sample(oggetto,n,replace=FALSE)
dove:
117
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
— l’oggetto specificato può avere modalità numerica o alfanumerica indifferentemente;
— n indica la dimensione del campione che si desidera estrarre. Si ricordi che per
default si ha n=length(oggetto);
— replace=FALSE indica che l’estrazione avviene senza rimessa; tale è la situazione
di default.
Esempio 4.3.1 Estrazione senza rimessa di un campione casuale di dimensione n = 5 dalle
26 lettere dell’alfabeto anglosassone. Il probbema è risolto con:
> sample(letters,5)
[1] "a" "m" "t" "g" "u"
♥
Esempio 4.3.2 Estrazione senza rimessa di 4 campioni casuali di dimensione ni = 1, . . . , 4,
con i = 1, . . . , 4, dalle 26 lettere dell’alfabeto anglosassone. Ricorrendo ad un ciclo retto da
for, abbiamo:
> for(n
[1] "m"
[1] "b"
[1] "e"
[1] "d"
in 1:4){print(sample(letters,n))}
"c"
"o" "c"
"y" "g" "m"
♥
Esempio 4.3.3 Campionamento con rimessa da un oggetto con modalità alfanumerica:
a<-LETTERS[1:7]
for(i in 1:4){print(sample(a,4,replace=TRUE))}
il cui risultato potrebbe essere:
[1]
[1]
[1]
[1]
"C"
"C"
"G"
"E"
"F"
"E"
"G"
"E"
"D"
"C"
"A"
"G"
"G"
"D"
"F"
"G"
Osservazione 4.3.1 Ricorrendo all’istruzione:
for(i in 1:4); print(sample(a,replace=TRUE))
si ottengono quattro permutazioni degli elementi di a; ad esempio le seguenti:
118
E. D. Isaia, Linguaggio R e applicazioni statistiche
[1]
[1]
[1]
[1]
"D"
"F"
"D"
"E"
"B"
"D"
"A"
"G"
"E"
"E"
"B"
"C"
"A"
"G"
"G"
"D"
"G"
"C"
"G"
"C"
"C"
"A"
"F"
"D"
"F"
"B"
"D"
"F"
♥
Esempio 4.3.4 Estrazione senza rimessa di 4 campioni di 5 elementi ciascuno, da una v.c.
N (10, 2).
> for(i in 1:4){print(sample(rnorm(1000,10,2),5))}
[1] 7.500336 11.596424 11.279172 10.808307 9.332722
[1] 11.683638 11.538254 9.494141 8.657761 8.943494
[1] 8.721086 11.026309 6.303418 8.370027 11.259078
[1] 8.636034 9.080102 12.447917 11.931348 7.070856
Esempio 4.3.5 Simulazione del lancio di una moneta ripetuto 10000 volte. Eseguiamo un’estrazione con rimessa, che ripetiamo 10000 volte, da un oggetto che contiene i valori 0 e 1. A
tal fine è sufficiente l’istruzione:
> sample(c(0,1),10000,replace=TRUE)
> ## non mandare in esecuzione!!
Meglio potremmo fare riassumendo i risultati in una tabella di frequenza, ad esempio mediante
le istruzioni:
> lancio<-table(sample(c(0,1), 10000, replace = TRUE))
> dimnames(lancio)<-list(Lancio=c("Testa","Croce"))
> lancio
Lancio
Testa Croce
4973 5027
Manifestamente resta aperto il problema della bontà della simulazione, ma su tale argomento
torneremo nel seguito.
♥
119
Capitolo 5
Elementi di statistica inferenziale
Nel seguito ci occuperemo del problema della costruzione di intervalli di confidenza e
della verifica di ipotesi statsitiche, perlomeno in situazioni, per cosı̀ dire, classiche. In
particolare vedremo come sia possibile e parimenti facile costruire funzioni ad hoc e, al
contempo, come si possano sfruttare funzioni già implementate e piuttosto sofisticate,
presenti nella libreria ctest.
Ricordiamo1 che la stima puntuale dei parametri θ = (θ 1 , θ2 , . . . , θk ) ∈ Θ ⊆ IRk ,
che caratterizzano la densità f X (x; θ) della una v.c. X, che descrive un fenomeno
aleatorio oggetto di indagine, avviene ricorrendo ad una opportuna funzione applicata sulle n ≥ 2 v.c. X1 , X2 , . . . , Xn indipendenti e identicamente distribuite (i.i.d.)
come X. La funzione T = t(X1 , X2 , . . . , Xn ) = t(X), abitualmente detta stimatore
ed individuata in genere in accordo a particolari criteri, ad esempio quello della massimaverosomiglianza o quello
dei momenti,
è a sua volta una v.c. con densità f T (τ ) e
"
#
tale che2 IE[T ] = θ e IE (T − IE[T ])2 = V ar[T ] ↓ 0, per n ↑ ∞.
5.1
Intervalli di confidenza per un parametro θ
Dato il campione casuale X = (X1 , X2 , . . . , Xn ) con densità fX (x, θ), dove θ è
un parametro unidimensionale e date le due statistiche T 1 = t1 (X1 , X2 , . . . , Xn ) e
T2 = t2 (X1 , X2 , . . . , Xn ), con T1 ≤ T2 , l’intervallo [T1 , T2 ] viene detto intervallo di
confidenza al livello 1 − α per il parametro θ se ∀ θ ∈ Θ ⊆ IR:
P [T1 ≤ θ ≤ T2 ; θ] = 1 − α
(5.1)
con 0 ≤ α ≤ 1. In particolare la (5.1) afferma che la probabilità che l’intervallo casuale
[T1 , T2 ] contenga il vero ed ignoto valore del parametro θ è 1 − α, qualunque sia il vero
valore del parametro assunto nello spazio parametrico. In tal modo le n osservazioni
1
Per approfondimenti: Shao (1999), Schervish (1997).
Trattasi delle note proprietà di correttezza e di consistenza, perlomeno asintotica, di uno
stimatore.
2
E. D. Isaia, Linguaggio R e applicazioni statistiche
campionarie, raccolte nel vettore x, vengono impiegate per individuare un insieme di
valori che, con una certa “fiducia”, conterrà il vero valore del parametro.
È bene tenere a mente che oltre agli intervalli di confidenza corrispondenti alla (5.1),
possiamo considerare intervalli di confidenza unilaterali del tipo:
P [T1 ≤ θ; θ] = 1 − α
(5.2)
P [T2 ≥ θ; θ] = 1 − α
(5.3)
Dal punto di vista pratico, tra i diversi metodi che consentono la costruzione di
intervalli di confidenza, vale la pena ricordare quello basato sulla “quantità pivotale”, cioè una funzione3 delle osservazioni campionarie e del parametro θ, diciamo
q (X1 , X2 , . . . , Xn ; θ), la cui distribuzione non dipende dal parametro θ. Ciò premesso,
sarà possibile individuare due valori q 1;α e q2;α che verranno a dipendere unicamente
da α e tali che:
P [q1;α ≤ q (X1 , X2 , . . . , Xn ; θ) ≤ q2;α ; θ] = 1 − α
(5.4)
A questo punto, se possiamo esprimere l’insieme:
{x1 , x2 , . . . , xn : q1;α ≤ q (x1 , x2 , . . . , xn ; θ) ≤ q2;α }
nella forma:
{x1 , x2 , . . . , xn : t1 (x1 , x2 , . . . , xn ) ≤ θ ≤ t2 (x1 , x2 , . . . , xn )}
dove t1 (·) e t2 (·) sono funzioni non dipendenti da θ, allora l’intervallo:
[t1 (X1 , X2 , . . . , Xn ) , t2 (X1 , X2 , . . . , Xn )]
è un intervallo di confidenza al livello 1 − α per θ.
A ben vedere, la relazione (5.4) non necessariamente è soddisfatta da un’unica coppia
(q1;α , q2;α ); generalmente questi vengono individuati in modo da lasciare una uguale
probabilità, pari ad α/2, nelle code sinistra e destra della distribuzione della quantità
pivotale q (X1 , X2 , . . . , Xn ; θ).
Dal punto di vista applicativo, grande importanza rivestono gli intervalli di confidenza
per campioni tratti da una distribuzione normale, cioè qualora si ipotizzi che le v.c.
X1 , X2 , . . . , Xn siano i.i.d. ∼ N (µ, σ 2 ). Sotto tale ipotesi, per gli stimatori:
X̄ = n−1
n
!
i=1
3
Xi
S 2 = (n − 1)−1
n
!
,
i=1
Xi − X̄
-2
In genere una quantità pivotale non è uno stimatore, dal momento che viene a dipendere da θ.
121
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
risultano le seguenti quantità pivotali:
Z=
√ X̄ − µ
n
∼ N (0, 1)
σ
W = (n − 1)
S2
2
2 ∼ χn−1
σ
Ricordando, inoltre, che le v.c. Z e W sono stocasticamente indipendenti, la v.c.:
U=
√
√ X̄ − µ
Z
n−1 √ = n
S
W
viene a possedere distribuzione t di Student con ν = n − 1 gradi di libertà.
Ciò premesso, vediamo come applicare quanto esposto in alcuni casi pratici.
Esempio 5.1.1 La costruzione di un intervallo di confidenza per il parametro θ = µ av(
√ X̄ − µ
ha
viene ricorrendo allo stimatore X̄ = n−1 ni=1 Xi . Dal momento che U = n S
2
distribuzione t di Student con ν = n − 1 gradi di libertà, allora ∀ µ, σ :
1−α =
=
)
*
√ X̄ − µ
P |U | ≤ n−1 t1−α/2 = P | n
| ≤ n−1 t1−α/2 =
S
)
*
S
S
P X̄ − n−1 t1−α/2 √ ≤ µ ≤ X̄ + n−1 t1−α/2 √
n
n
"
#
dove n−1 t1−α/2 indica il quantile di ordine 1−α/2 della distribuzione t di Student con ν = n−1
gradi di libertà.
Pertanto, stabilito il livello di confidenza 1 − α, avremo:
)
*
S
S
ICµ = X̄ − ν t1−α/2 √ ; X̄ + ν t1−α/2 √
n
n
√
Si osservi che la v.c. S/ n, detta abitualmente errore standard, rappresenta la stima della
varianza dello stimatore X̄, media campionaria.
Desiderando automatizzare quanto esposto, possiamo considerare la seguente:
1
2
3
4
5
6
7
8
9
10
Funzione 5.1.1 (I.C. per µ, σ 2 ignota)
> ic.mu<-function(x,alpha=0.05,decimali=4)
{
n<-length(x)
media.x<-mean(x)
sd.x<-sd(x)
se.x<-sd(x)/sqrt(n)
ic.inf<-media.x-qt(1-alpha/2,n-1)*se.x
ic.sup<-media.x+qt(1-alpha/2,n-1)*se.x
cat("I.C.: ",round(ic.inf,decimali),round(ic.sup,decimali),"\n")
}
122
E. D. Isaia, Linguaggio R e applicazioni statistiche
Cosı̀, ad esempio, per le n = 12 osservazioni:
> x<-c(14.2,13.8,10.1,12.4,11.1,11.3,8.1,11.3,7.8,8.0,9.3,5.9)
otteniamo:
> ic.mu(x,alpha=.05)
I.C.: 8.6576 11.8924
Esempio 5.1.2 La costruzione di un intervallo di confidenza per il parametro θ = σ 2 avviene
2
(n
ricorrendo allo stimatore S = (n − 1)−1 i=1 Xi . Dal momento che W = (n − 1) S2 ha
σ
distribuzione Chi-Quadro con ν = n − 1 gradi di libertà:
)
*
)
*
S2
(n − 1) S 2
2
1 − α = P [W ≤ χn−1;1−α ] = P (n − 1) 2 ≤ χn−1;1−α = P σ ≤
χn−1;1−α
σ
da cui l’intervallo di confidenza:
ICσ2
)
(n − 1) S 2
= 0;
χn−1;1−α
*
Anche in questo caso, desiderando automatizzare quanto esposto, possiamo considerare la
seguente:
1
2
3
4
5
6
7
8
Funzione 5.1.2 (I.C. per σ 2 )
> ic.var<-function(x,alpha=0.05,decimali=4)
{
n<-length(x)
var.x<-(n-1)*var(x)
ic.inf<-0
ic.sup<-var.x/qchisq(1-alpha/2,n-1)
cat("I.C.: ",round(ic.inf,decimali),round(ic.sup,decimali),"\n")
}
Cosı̀, ad esempio, per le n = 12 osservazioni:
> x<-c(14.2,13.8,10.1,12.4,11.1,11.3,8.1,11.3,7.8,8.0,9.3,5.9)
abbiamo:
> ic.var(x,alpha=.05)
I.C.: 0 3.2519
♥
123
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Esempio 5.1.3 Siano X1 e X2 due campioni casuali indipendenti, di numerosità rispettivamente n1 e n2 , tratti da altrettante v.c. N (µi , σi2 ), con i = 1, 2. La costruzione di un
intervallo di confidenza per la differenza tra due valori medi µ1 − µ2 prende le mosse dalla
v.c. X̄1 − X̄2 , a componenti indipendenti. Se le varianze σ12 e σ22 , entrambe ignote, si possano
ritenere uguali tra loro, allora la v.c.:
U=
√
(X̄1 − X̄2 ) − (µ1 − µ2 )
n1 + n 2
Sp
(5.5)
con:
Sp2 =
(n1 − 1) S12 + (n2 − 1) S22
n1 + n 2 − 2
risulta avere distribuzione t di Student con ν = n1 + n2 − 2 gradi di libertà. Pertanto:
1−α =
=
≤
)
√
(X̄1 − X̄2 ) − (µ1 − µ2 )
| ≤ n1 +n2 −2 t1−α/2
P | n1 + n 2
Sp
)
Sp
P (X̄1 − X̄2 ) − n1 +n2 −2 t1−α/2 √
≤ µ1 − µ2
n1 + n 2
*
Sp
(X̄1 − X̄2 ) + n1 +n2 −2 t1−α/2 √
n1 + n 2
*
Quindi l’intervallo di confidenza (ICµ1 −µ2 ) per la differenza tra due valori medi risulta:
)
Sp
Sp
(X̄1 − X̄2 ) − n1 +n2 −2 t1−α/2 √
; (X̄1 − X̄2 ) + n1 +n2 −2 t1−α/2 √
n1 + n 2
n1 + n 2
*
Anche in questo caso, desiderando automatizzare quanto esposto, possiamo considerare la
seguente:
1
2
3
4
5
6
7
8
9
10
11
2
2
Funzione 5.1.3 (I.C. per µX − µY , σX
= σX
ma ignote)
> ic.muxy<-function(x,y,alpha=0.05,decimali=4)
{
nx<-length(x)
ny<-length(y)
media.dif<-mean(x)-mean(y)
sp<-sqrt(((nx-1)*var(x)+(ny-1)*var(y))/
(nx+ny-2))*sqrt((1/nx)+(1/ny))
ic.inf<-media.dif-qt(1-alpha/2,nx+ny-2)*sp
ic.sup<-media.dif+qt(1-alpha/2,nx+ny-2)*sp
cat("I.C.: ",round(ic.inf,decimali),round(ic.sup,decimali),"\n")
}
> ic.muxy(x,y,alpha=.05)
I.C.: -5.1259 0.6502
124
E. D. Isaia, Linguaggio R e applicazioni statistiche
Osservazione 5.1.1 Se l’ipotesi di uguaglianza 4 tra le due varianze σ12 e σ22 non
potesse essere assunta, allora si dimostra che la funzione test (5.5) viene ad essere distribuita approssimativamente secondo una t di Student i cui gradi di libertà vengono
stimati mediante l’approssimatione di Welch-Satterthwaite:
ν=
4
2 −1
S12 n−1
1 + S2 n2
6
S12 n−1
S 2 n−1
1
+ 2 2
n1 − 1
n2 − 1
Evidentemente, ν non è necessariamente un intero: in tal caso lo si approssima all’intero immediatamente precedente. Quello che ne risulta è una distribuzione t di
Student con numero di gradi di libertà minore di n 1 + n2 − 2 .
L’output delle funzioni precedentemente introdotte, può ovviamente essere arricchito
con l’aggiunta di commenti ed altre informazioni, oltre al desiderato intervallo di
confidenza.
Cosı̀, ad esempio, la funzione (5.1.1) potrebbe esere riscritta come:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ic.mu<-function(x,alpha=0.05,decimali=4)
{
n<-length(x)
media.x<-mean(x)
sd.x<-sd(x)
se.x<-sd(x)/sqrt(n)
ic.inf<-media.x-qt(1-alpha/2,n-1)*se.x
ic.sup<-media.x+qt(1-alpha/2,n-1)*se.x
ris<-c(1:3)
ris[1]<-round(media.x, decimali)
ris[2]<-round(sd.x, decimali)
ris[3]<-round(se.x, decimali)
ris<-matrix(ris,ncol=1)
dimnames(ris)<-list(c("Media campionaria","Deviazione standard:",
"Standard error:"),"")
cat("Vettore dei dati individuali: ", deparse(substitute(x)),
"\nOsservazioni: ", n,"\n","\n---------------------------",
"\n","I.C.: ",round(ic.inf,decimali)," ; ",
round(ic.sup,decimali),"\n----------------------------",
"\n","\nStatistiche:","\n")
ris
}
4
In termini tecnici si parla di ipotesi di omoschedasticità tra le varianze.
125
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
A tal proposito, per le n = 12 osservazioni precedentemente impiegate:
> x<-c(14.2,13.8,10.1,12.4,11.1,11.3,8.1,11.3,7.8,8.0,9.3,5.9)
otteniamo:
> ic.mu(x,alpha=.05,decimali=3)
Vettore dei dati individuali: x
Osservazioni: 12
--------------------------I.C.: 8.658 ; 11.892
---------------------------Statistiche:
Media campionaria
10.275
Deviazione standard: 2.546
Standard error:
0.735
I risultati proposti in questo paragrafo, in virtù del Teorema Limite Centrale, possono essere approssimativamente applicati a campioni tratti da distribuzioni non
necessariamente normali, a patto però che la cardinalità n sia sufficientemente grande.
Esempio 5.1.4 Una moneta, di cui si ignora se sia equilibrata o no, viene lanciata n = 100
volte. Indicando con π la probabilità, costante, di ottenere “Croce” in un singolo lancio, ci
proponiamo la costruzione di un intervallo di confidenza per π, a partire dal campione casuale
X1 , X2 , . . . , Xn , le cui componenti Xi risultano v.c. indipendenti con, ciascuna, distribuzione
bernoulliana, cioè, ∀ i = 1, 2, . . . , n:
Xi =
+
0
1
1−π
π
A tal fine (cfr. Esempio 4.3.5), si immagini che l’esperimento casuale abbia dato luogo ai
seguenti valori:
> lancio<-sample(c(0,1), 100, replace = TRUE)
> lancio
[1] 0 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1 0 1 1 1 0 1 1 1 1 1
[27] 0 1 0 1 0 0 0 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 0 1
[53] 0 0 0 1 1 0 0 0 1 0 0 0 1 0 0 1 0 0 1 1 1 1 1 1 1 1
[79] 1 1 0 1 1 0 0 1 1 0 1 1 1 1 1 1 1 1 1 0 1 0
> dimnames(table(lancio))<-list(Lancio=c("Testa","Croce"))
126
E. D. Isaia, Linguaggio R e applicazioni statistiche
> table(lancio)
Lancio
Testa Croce
40
60
(
Stimatore di π viene ad essere la v.c. X̄ = ni=1 n−1 Xi , detta in tal caso proporzione campionaria, che indica, appunto, la proporzione delle Croci ottenute nella n-pla osservata. Dal
momento che n è grande, possiamo fare appello al Teorema Limite Centrale ed affermare che
π (1 − π)
la distrbuzione di X̄ è approssimativamente Normale con parametri π e
. L’intervallo
n
di confidenza sarà, dunque:
:
<
;
;
x̄ (1 − x̄)
x̄ (1 − x̄)
ICµ = x̄ − ν t1−α/2
; x̄ + ν t1−α/2
n
n
la cui valutazione in R avviene mediante l’istruzione:
> ic.mu(lancio,alpha=.05)
Vettore dei dati individuali:
Osservazioni: 100
lancio
--------------------------I.C.: 0.5337 ; 0.7263
---------------------------Statistiche:
Media campionaria
Deviazione standard:
Standard error:
0.63
0.4852
0.0485
Si osservi che l’intervallo di confidenza ottenuto non contiene il valore 0.5.
♥
Va da sé che qualora non si possa ricorrere al Teorema Limite Centrale occorre individuare la distribuzione esatta degli stimatori dei parametri di interesse, il che
generalmente comporta alcuni problemi sopratutto ai fini del calcolo numerico.
Senza voler entrare in dettagli, tentiamo di illustrare il problema prendendo spunto
dalla situazione di cui all’Esempio 5.1.4. Supponiamo, dunque, che X sia una v.c.
con distribuzione bernoulliana di parametro ignoto π. Al fine di stimare π, estratto il
campione casuale X1 , X2 , . . . , Xn , di dimensione n, possiamo ricorrere allo stimatore
(
T = ni=1 Xi che rappresenta il nmero dei successi ottenuti in X. Manifestamente
tale stimatore, in quanto somma di n v.c. i.i.d. bernoulliane, possiede distribuzione
binomiale di parametri n e π con 5 con IE[T ] = n π e V ar[T ] = n π (1 − π).
5
Si noti che tra lo stimatore X̄ di cui all’Esempio 5.1.4 e lo stimatore T qui introdotto intercorre
la semplice relazione X̄ = n−1 T .
127
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Al fine della costruzione di un intervallo di confidenza per π, al livello di confidenza
1 − α, occorre individuare i quantili di ordine α/2 e 1 − α/2 della distribuzione di T ,
ossia risolvere rispetto a ki , i = 1, 2, le equazioni:
P [T ≤ k1 ] =
k1
!
px (1 − p)n−x = α
(5.6)
P [T ≤ k2 ] =
k2
!
px (1 − p)n−x = 1 − α
(5.7)
t=0
t=0
dove p rappresenta la stima puntuale di π, ovvero p = t(x)/n.
Il calcolo dei quantili k1 e k2 , in accordo alle (5.6) e (5.7), può essere eseguito ricorrendo al comando uniroot (cfr. paragrafo ??) applicato sulla funzione di ripartizione
di una binomiale di parametri n, p. Pertanto possiamo considerare la seguente:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Funzione 5.1.4 (I.C. esatto per π)
ic.p<-function(x,n,livello.conf=0.95)
{
p<-x/n
alpha<-(1-livello.conf)/2
LI<-function(x,alpha)
{
uniroot(function(p) pbinom(x-1,n,p)-livello.conf,c(0,1))$root
}
LS<-function(x, alpha)
{
uniroot(function(p) pbinom(x,n,p)-alpha,c(0,1))$root
}
IC<-{c(LI(x,alpha), LS(x,alpha))}
stima.p<-x/n
cat("Stima =",stima.p ,"\n")
cat("IC =",IC,"\n")
}
Esempio 5.1.5 Con riferimento all’esperimento casuale di cui all’Esempio 5.1.4, avendo osservato 60 Croci in 100 lanci di una stessa moneta, l’intervallo di confidenza esatto per il
parametro π risulta:
> ic.p(60,100)
Stima = 0.6
IC = 0.5129658 0.6967233
più piccolo rispetto a quanto ottenuto applicando il Teorema Limite Centrale.
128
♥
E. D. Isaia, Linguaggio R e applicazioni statistiche
5.2
Verifica di ipotesi statistiche
Dato un campione casuale (X1 , X2 , . . . , Xn ) di dimensione n tratto da una v.c. X con
densità fX (x; θ) nota a meno dei parametri θ = (θ 1 , θ2 , . . . , θk ) ∈ Θ ⊆ IRk , un’ipotesi
statistica può essere intesa quale asserzione sul vettore dei parametri della densità del
tipo H : θ ∈ Θ0 , ove Θ0 è un sottoinsieme dello spazio parametrico Θ. In particolare
l’ipotesi H viene detta semplice se Θ 0 contiene un solo elemento, composta qualora
contenga più elementi. Il problema che ci si pone è stabilire se θ ∈ Θ 0 oppure no.
Abitualmente il problema viene posto ricorrendo ad un sistema di ipotesi del tipo:
+
H0 : θ ∈ Θ0
H1 : θ ∈ Θ1
con Θ0 ∪Θ1 = Θ e Θ0 ∩Θ1 = ∅. La prima asserzione è detta ipotesi nulla e rappresenta
l’ipotesi che si desidera testare, la seconda viene detta ipotesi alternativa.
Sulla base dei risultati forniti dalla n-pla osservata, si perverrà a decidere se l’ipotesi
nulla è sostenuta dai dati o se questi invece sono a favore dell’ipotesi alternativa. Con
il termine test statistico si intende appunto la procedura di decisione in favore di H 0
o di H1 .
Più precisamente, un test statistico π (x) viene ad essere una funzione che assume
valore π0 se i dati campionari portano all’accettazione di H 0 e π1 in caso contrario.
In sostanza, esso viene a creare una partizione dello spazio campionario; tutti gli
elementi dello spazio campionario per cui π (x) = π 0 vengono a costituire la regione
di accettazione di H0 , A = {x : π (x) = π0 }, mentre l’insieme complementare, Ā =
{x : π (x) = π1 }, costituisce regione di rifiuto di H 0 . In definitiva, dunque, se x ∈ A
si accetta l’ipotesi nulla, la si rigetta qualora x ∈ Ā.
Tale modo di procedere, tuttavia, ci espone a due particolari rischi:
— rigettare l’ipotesi nulla, quando in realtà essa è vera;
— accettare l’ipotesi nulla, quando in realtà essa è falsa.
In letteratura, tali errori vengono, rispettivamente detti errore del primo tipo ed
errore del secondo tipo. Appare, quindi, intuitivo che un test statistico debba tentare
di minimizzare la probabilità di commettere entrambi i due tipi di errore. Per ogni
testo statistico possiamo definire la funzione di potenza:
"
#
K (θ) = P X ∈ Ā; θ = P [π (X) = π1 ; θ]
(5.8)
cioè come la probabilità di rifiutare l’ipotesi nulla per ogni valore del parametro θ.
Sotto tale profilo, dunque, un test statistico verrà considerato “ottimo” se al contempo minimizza la (5.8) per θ ∈ Θ0 e viceversa massimizza la (5.8) per θ ∈ Θ 1 .
129
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Evidentemente, tale condizione non può essere verificata poiché i due requisiti sono
in conflitto tra loro. In pratica, la risoluzione del problema avviene fissando in modo
arbitrario il cosidetto livello di significatività del test, definito:
"
α = sup K (θ) = sup P X ∈ Ā; θ
θ∈Θ0
θ∈Θ0
#
(5.9)
cioè la probabilità di commettere l’errore del primo tipo. " Osserviamo
ancora che,
#
qualora Θ0 sia semplice, allora il livello del test è α = P X ∈ Ā; θ0 . Quanto alla
probabilità di commettere il secondo tipo di errore, questa viene indicata con β (θ) =
P [X ∈ A; θ ∈ Θ1 ] = 1 − K (θ).
A questo punto, fissato il livello di significatività, nella famiglia dei test di livello
preassegnato, verrà scelto un test tale che β (θ) sia uniformemente minimizzata su
Θ1 , ovvero tale che K (θ) venga uniformemente massimizzata in Θ 1 . Un siffatto test
viene detto uniformemente più potente. Quindi un test ottimo sarà definito come
quel test che per α assegnato ha potenza massima.
È importante osservare che alla partizione dello spazio campionario, indotta dal test
statistico, viene associata una funzione a valori reali detta abitualmente funzione test,
e coincidente con una statistica t (x) che assume valori piccoli quando H 0 è vera e
valori elevati quando è vera H 1 . Possiamo quindi dire che un test statistico è una
procedura basata su un campione casuale tramite una funzione test con la quale H 0
è rigettata a favore di H1 per certi valori estremi della funzione test ed accettata per
i restanti valori possibili.
Ne seguito ci limitiamo a presentare una collezione di funzioni test 6 utili in svariate
situazioni ed implementate in R, mentre non ci occuperemo della costruzione di test
ottimali.
È importante osservare, Gibbon, Pratt (1975), che è norma comune stabilire qual’è il
più piccolo livello per il quale la n-pla osservata conduce al rifiuto dell’ipotesi nulla.
Ciò avviene valutando il valore osservato t della funzione test tramite il livello di
significatività osservato o p-value, definito:
p − value = sup P [t (X) > t; θ]
(5.10)
θ∈Θ0
Tanto più il p − value è piccolo, tanto minore sarà la probabilità che sotto l’ipotesi
nulla la funzione test produca un valore maggiore di quello osservato, mentre è alta
la probabilità sotto l’ipotesi alternativa. In pratica tanto più è piccolo il p − value,
tanto più saremo propensi ad accettare H 0 .
Posto che θ sia il parametro unidimensionale di interesse e indicando con T = t (X)
una funzione test, i diversi tipi di ipotesi su θ che affronteremo nel seguito saranno:
6
Funzioni test a potenza massima e basati sul rapporto tra le funzioni di verosomiglianza calcolate
sotto H0 e H1 .
130
E. D. Isaia, Linguaggio R e applicazioni statistiche
Ipotesi nulla
H0 : θ = θ 0
Ipotesi altenative
H1 : θ 3= θ0
H1 : θ > θ 0
H1 : θ < θ 0
ipotesi bidirezionale
ipotesi unidirezionale
ipotesi unidirezionale
mentre i corrispondenti p − value saranno calcolati in base alla distrbuzione della
funzione test T = t (X) sotto l’ipotesi nulla, ponendo cioè θ = θ 0 .
Desiderando in qualche modo chiarire quanto sin qui riassunto, valga il seguente:
Esempio 5.2.1 I responsabili di un Istituto di Credito ritengono che l’importo dei prelievi
effettuati con il Bancomat, presso il proprio sportello, abbiano una distribuzione approssimativamente normale con valor medio pari a 300.000 lire. Al fine di verificare tale affermazione, è
stato estratto un campione casuale di dimensione n = 40 il quale ha fornito i seguenti risultati
(in lire x 1000):
350
150
150
200
300
350
400
350
200
250
350
500
450
300
550
450
250
250
500
250
350
250
250
350
250
550
350
250
350
150
350
100
250
250
550
350
300
350
450
350
Si immagini che il sistema di ipotesi statistiche che si desidera sottoporre a verifica sia:
+
H0 : µ = µ0 = 300
H1 : µ > µ0 = 300
Manifestamente trattasi di una verifica di ipotesi, con alternativa unilaterale, sul valor medio
di una distribuzione normale con varianza ignota; la funzione test che verrà utilizzata è quella
che prevede la stima di σ 2 mediante la varianza campionaria corretta S 2 , e pertanto:
T = t (X) =
√ X̄ − µ
n
S
che, sotto H0 , ha distribuzione t di Student con ν = n − 1 gradi di libertà. Per la natura
dell’ipotesi alternativa H1 , segue che la regione di rifiuto è Ā = {x : t(x) > k}, dove k indica
il valore critico della funzione test determinato in modo da soddisfare la (5.9), cioè:
"
#
P X ∈ Ā; µ0 = P [T > k; µ0 ] = α
Se si sceglie di porre α = 0.05, otteniamo, per ν = 39, quale valore critico k = 1.6849 e la
√
regola di decisione porterà al rigetto di H0 qualora sia tSper. = 40 x̄ −s300 > k.
In R possiamo impartire i comandi:
> x<-c(350,300,200,450,250,350,250,350,250,300,150,350,250,300,250,
250,550,150,250,350,150,400,350,550,500,250,350,350,550,450,
200,350,500,450,250,350,250,100,350,350)
> alpha<-0.05
> k.critico<-qt(1-alpha,length(x)-1)
> t.sper<-(sqrt(40))*(mean(x)-300)/sd(x)
131
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
donde i risulati:
> k.critico
[1] 1.684875
> t.sper
[1] 1.320101
che, per le ipotesi di lavoro fatte, condurrebbero all’accettazione di H0 .
Osservazione 5.2.1 Per la simmetria della distribuzione della funzione test risulta t1−α;ν =
−tα;ν , pertanto ai fini del calcolo del valore critico del test avremmo potuto impartire il
comando:
> k.critico<-qt(alpha, length(x)-1, lower=FALSE)
del tutto equivalente a:
> k.critico<-qt(1-alpha, length(x)-1)
oppure a:
> k.critico<- -qt(alpha, length(x)-1)
Tale approccio, tuttavia, non viene in pratica utilizzato dai pacchetti statistici in commercio,
i quali forniscono il p − value associato alla verifica di ipotesi richiesta in accordo alla (5.10).
Nel caso in esame, indicando con fT (t; µ0 ) la densità della funzione test sotto H0 , avremo:
p.value =
=
+∞
tSper.
fT (t; µ0 ) dt = 1 −
=
tSper.
fT (t; µ0 ) dt
−∞
e di conseguenza in R:
> p.value<-1-pt(t.sper,length(x)-1)
> p.value
[1] 0.09724868
il che indica che l’area della coda a destra del quantile tSper. della distribuzione t di Student
con ν = 39 gradi di libertà è all’incirca il 10%. Anche sotto tale ottica si è propensi ad
accettare H0 .
A questo punto, per avere un’idea del potere discriminatorio del test"approntato,
# potrebbe
essere interessante calcolare la funzione di potenza del test, K (µ) = P X ∈ Ā; µ , perlomeno
in corrispondenza ad alcuni valori di µ sotto H1 . Ciò equivale a calcolare il complemento ad
uno della funzione di ripartizione di una ditribuzione t di Student, con ν = n − 1 gradi di
√ µ −µ
libertà e parametro di non centralità n 1 S 0 , in corrispondenza a k = 1.6849.
Scelto di porre, sotto H1 , µ1 = 310 e ricordando le Osservazioni 4.0.4 e 5.2.1, in R possiamo
impartire i comandi:
132
E. D. Isaia, Linguaggio R e applicazioni statistiche
> mu1<-310
> mu0<-300
> sqm<-sd(x)
> nonc<-sqrt(length(x))*(mu1-mu0)/sd(x)
> pt(qt(alpha, df=length(x)-1), df=length(x)-1, ncp = nonc, lower = FALSE)
[1] 0.98578
La potenza del test, in corrispondenza dell’ipotesi alternativa µ1 = 310, vale pertanto 0.98578.
In altri termini β (µ1 = 310) = P [X ∈ A; µ1 = 310] = 0.01422, ovvero una probabilità di circa
il 1.4% di commettere l’errore del II tipo in corrsIpondenza a µ1 = 310.
♥
Alla luce dell’Esempio proposto, appare evidente come in R possano essere implementate funzioni ad hoc per la verifica di ipotesi statistiche e a tal proposito valga il
seguente:
Esempio 5.2.2 Desiderando verificare l’ipotesi di omoschedasticità tra due varianze H 0 :
2
2
σX
/σY2 = 1 contro l’alternativa H1 : σX
/σY2 > 1, in base alle realizzazioni di due campioni
2
indipendenti tratti dalle v.c. X ∼ N (µX , σX
) e Y ∼ N (µY , σY2 ), ricordando che la statistica
2
2
campionaria SX /SY , sotto l’ipotesi nulla, ha distribuzione F di Snedecor con nX − 1 e nY − 1
gradi di libertà rispettivamente a numeratore e denominatore, posiamo introdurre la seguente
funzione ad hoc:
1
2
3
4
5
6
7
8
9
10
11
Funzione 5.2.1 (Verifica di ipotesi per due varianze)
> var.equal<-function(x,y)
{
ok <- (!is.na(x) & !is.na(y))
x <- x[ok]; y <- y[ok]
nx <- length(x); ny <- length(y)
if(nx <= 2 || ny <= 2) stop("not enough observations")
Fsper<-sqrt(var(x))/sqrt(var(y))
pvalue<-1-pf(Fsper, nx-1, ny-1)
sigma<-list(vx=var(x),vy=var(y),rapporto=Fsper,pval=pvalue)
return(sigma)
}
A commento della funzione proposta:
— le righe da [2] a [5] si occupano del controllo dei vettori x e y immessi;
— la riga [6] provvede al calcolo del valore sperimentale della funzione test impiegata;
— in riga [7] si procede al calcolo del p − value associato al test in accordo alla (5.10).
— in riga [8] si crea la lista sigma che contiene i risultati del test (varianze campionarie,
valore sperimentale della funzione test e corrispondente p − value);
— l’istruzione in riga [9] visualizza la lista sigma.
133
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Lasciamo come esercizio al Lettore il problema del calcolo della potenza del test in corrispon2
denza ad un particolare valore del rapporto σX
/σY2 sotto l’ipotesi alternativa7.
♥
Prima di concludere, desideriamo accennare al problema dell’individuazione della dimensione n del campione casuale sı̀ che essa garantisca, a fronte di un dato sistema
di ipotesi statistiche, prefissate probabilità di commettere sia l’errore del I tipo che
l’errore del II tipo, questa valutata in corrispondenza di un particolare valore cruciale
θ ∈ Θ1 . Il problema viene superato, fissate le probabilità α e β(θ ∈ Θ 1 ), risolvendo
rispetto ad n l’equazione:
K(θ ∈ Θ1 ) = 1 − β(θ ∈ Θ1 )
(5.11)
Dal momento che generalmente le funzioni test coinvolte hanno, perlomeno sotto
l’ipotesi alternativa, una distribuzione non centrale, il problema può essere risolto
ricercando per via numerica le radici dell’equazione (5.11), sfruttando, ad esempio, il
comando uniroot, di cui al paragrafo (??).
Esempio 5.2.3 Si immagini che il contenuto, in ml, di flaconi di un certo medicinale siano
imbottigliati mediante due processi produttivi possa essere modellizzato mediante le due v.c.
X1 ∼ N (µ1 , σ 2 ) e X2 ∼ N (µ2 , σ 2 ), dove, in base a indagini precedenti, si ha la stima S 2 = 6.
Desiderando sottoporre a verifica le seguenti ipotesi statistiche:
+
H0 : µ1 − µ2 = 0
H1 : µ1 − µ2 > 0
si vuole determinare la numerosità campionaria che rispetti le seguenti condizioni:
— probabilità dell’errore del I tipo pari al 5%, ossia α = 0.05;
— potenza del test, in corrispondenza all’ipotesi alternativa µ1 − µ2 = 2 = δ, pari al 98%.
Ora, sappiamo che la funzione test, sotto l’ipotesi alternativa, ha distribuzione t di Student
>
con 2 (n − 1) gradi di libertà e parametro di non centralità n/2 δ2 ; sicché possiamo scrivere
S
l’espressione per K(δ) come:
> potenza<-quote
({
pt(qt(0.05, df=2*(n-1), lower = FALSE), df=2*(n-1), ncp=sqrt(n/2) *
2/sqrt(6), lower = FALSE)
})
Quindi, ricorrendo alla funzione uniroot (cfr. Esempio ??), e ricordando che per le ipotesi
fatte K(δ) = 0.98, abbiamo:
> n<-uniroot(function(n) eval(potenza) - 0.98, c(2, 1e+07))$root
> n
[1] 33.16656
sı̀ che la numerosità campionaria atta a garantire i vincoli posti sarà n = 2 · 34 = 68.
7
Cfr. Osservazione 4.0.4 ed Esempio 5.2.1.
134
♥
E. D. Isaia, Linguaggio R e applicazioni statistiche
5.3
La libreria ctest
In R è possibile procedere alla verifica di di ipotesi statistiche ricorrendo, come già si
disse, alle funzioni contenute nella libreria ctest, acronimo di “Common Tests”.
Prima di passare in rassegna ad alcune di esse, vediamo come è possibile accedere ad
una libreria, visualizzarne il contenuto ed eventualmente liberare l’area di lavoro dalle
librerie in eccesso. I comandi essenzialmente sono:
— library(nome della libreria): carica nell’area di lavoro corrente la libreria
specificata;
— (.packages()): elenca le librerie attive;
— help(package=nome della libreria): fornisce, nella finestra di Help, l’elenco
delle funzioni della libreria specificata;
— detach("package:nome della libreria"): libera l’area di lavoro corrente
dalla libreria specificata.
Nel nostro caso, essendo interessati alla libreria ctest, potremmo impartire i comandi:
> (.packages())
[1] "base"
> library(ctest)
> (.packages())
[1] "ctest" "base"
> detach("package:ctest")
> (.packages())
[1] "base"
In particolare, poi, il comando help(package=ctest) porge il seguente elenco 8 :
ansari.test Ansari-Bradley Test
bartlett.test Bartlett Test for Homogeneity of Variances
binom.test Exact Binomial Test
chisq.test Pearson’s Chi-squared Test for Count Data
cor.test Test for Zero Correlation
fisher.test Fisher’s Exact Test for Count Data
fligner.test Fligner-Killeen Test for Homogeneity of Variances
friedman.test Friedman Rank Sum Test
kruskal.test Kruskal-Wallis Rank Sum Test
8
Aggiornamento alla data 01.02.2001.
135
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
ks.test Kolmogorov-Smirnov Tests
mantelhaen.test Cochran-Mantel-Haenszel Chi-Squared Test
for Count Data
mcnemar.test McNemar’s Chi-squared Test for Count Data
mood.test Mood Two-Sample Test of Scale
wise.prop.test Pairwise comparisons of proportions
pairwise.t.test Pairwise t tests
pairwise.table Tabulate p values for pairwise comparisons
pairwise.wilcox.test Pairwise Wilcoxon rank sum tests
power.prop.test Power calculations two sample test for of proportions
power.t.test Power calculations for one and two sample t tests
print.pairwise.htest Print method for pairwise tests
print.power.htest Print method for power calculation object
prop.test Test for Equal or Given Proportions
prop.trend.test Test for trend in proportions
quade.test Quade Test
shapiro.test Shapiro-Wilk Normality Test
t.test Student’s t-Test
var.test F Test to Compare Two Variances
wilcox.test Wilcoxon Rank Sum and Signed Rank Tests
Test su valori medi — t.test
La funzione t.test è assai versatile, consentendo all’utente di effettuare una serie
piuttosto ampia di verifiche di ipotesi statistiche circa un valor medio o la differenza
tra due valori medi. La sintassi estesa della funzione in oggetto è:
t.test(x, y=NULL, alternative="two.sided", mu=0,
paired = FALSE, var.equal = FALSE, conf.level = 0.95)
Volendo procedere, conviene distinguere il caso in cui la verifica di ipotesi coinvolga
un solo valor medio da quello in cui si essa sia concentrata sulla differenza tra due
valori medi in base alle osservazioni di due campioni indipendenti ovvero appaiati.
In tutti i casi, l’output della funzione t.test consiste nella creazione e visualizzazione
della lista rval contenente tutte le informazioni relative al test richiesto (valore della
statistica test, p-value, intervallo di confidenza, ...)
Un solo campione Premesso che la semplice istruzione t.test(x) verifica, sulla base
della statistica campionaria x̄, le seguenti ipotesi H 0 : µ = µ0 = 0 contro H1 : µ 3= µ0 ,
il che è raramente di interesse, ci pare utile soffermarci sugli argomenti della funzione
in esame; pertanto:
136
E. D. Isaia, Linguaggio R e applicazioni statistiche
— indicato l’oggetto che contiene le determinazioni campionarie, occorre specificare
il valore di µ sotto l’ipotesi nulla, poiché come si è detto la situazione di default
lo pone uguale a zero;
— successivamente, a seconda della struttura dell’ipotesi alternativa si dovrà indicare se il test è di tipo bilaterale ovvero unilaterale a protezione inferiore o
superiore; a tal fine, valga la tabella riassuntiva che segue:
Ipotesi nulla
H0 : µ = µ0
Ipotesi altenative
H1 : µ 3= µ0
H1 : µ > µ0
H1 : µ < µ0
parametri
(...alternative="two.sided",...)
(...,alternative="greater",...)
(...,alternative="less",...)
— in ultimo l’utente può specificare il livello 1 − α desiderato nella costruzione dell’intervallo di confidenza per il valor medio incognito µ; la situazione di default
prevede conf.level=0.95.
Esempio 5.3.1 Un produttore di lampade fluorescenti asserisce che le proprie lampade hanno
una durata media di corretto funzionamento di 1200 ore. A fine di verificare tale affermazione,
abbiamo sottoposto a prova di durata un campione casuale di n = 10 lampade, ottenendo i
seguenti risultati circa la durata di corretto funzionamento (espressa in ore):
1179
1235
1180
1250
1220
1010
1000
1150
1277
Il sistema di ipotesi a conflitto è il seguente:
H0 : µ = 1200
H1 : µ < 1200
Desiderando procedere, ricorriamo alla funzione t.test:
> x<-c(1179,1235,1180,1250,1220,1010,1000,1150,1277,1129)
> t.test(x,y=NULL, alternative="less", mu=1200,paired = FALSE,
var.equal = FALSE, conf.level = 0.95)
One Sample t-test
data: x
t = -1.2345, df = 9, p-value = 0.1241
alternative hypothesis: true mean is less than 1200
95 percent confidence interval:
NA 1217.941
sample estimates:
mean of x
1163
137
1129
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Dal momento che il p-value associato al test è maggiore, seppur di poco, di 0.10, siamo
portati ad accettare l’ipotesi nulla. Si osservi che il valore di µ sotto l’ipotesi nulla H 0 rientra
nell’intervallo di confidenza [0; 1217.941].
♥
Due campioni indipendenti Nel caso si operi su due campioni casuali indipendenti, (X1 , X2 , . . . , XnX ) e (Y1 , Y2 , . . . , YnY ), e si desideri verificare l’ipotesi che essi
provengano da densità caratterizzate da un ugual valor medio, occorrerà:
— indicare gli oggetti, ad esempio x e y, che contengono le determinazioni campionarie;
— scegliere il tipo di test idoneo a seconda della struttura dell’ipotesi alternativa,
come si è visto al punto precedente (alternative="...");
— indicare che trattasi di determinazioni provenienti appunto da campioni indipendenti (paired=FALSE);
2 e σ 2 possono ritenersi tra loro uguali o non,
— specificare se le varianze ignote σ X
Y
ricordando che la situazione di default prevede var.equal=FALSE e in tal caso
i gradi di libertà della t di Student coinvolta sono stimati in accordo al metodo
proposto da Welch-Satterthwaite (cfr. Osservazione 5.1.1);
— stabilire il livello 1 − α desiderato nella costruzione dell’intervallo di confidenza
per la differenza tra i valori medi µ X e µY .
Esempio 5.3.2 Si immagini che i responsabili della Qualità, di un’azienda operante in campo
informatico, al fine di monatre dischi fissi di nuova generazione su propri PC si trovino a
dover scegliere tra due fornitori (A e B) che, a parità di prestazioni dichiarate, offrono prezzi
unitari tra loro diversi. Ai fini della scelta del componente a prezzo unitario minore, sono state
effettuate, per ciascun tipo di prodotto, più misurazioni (espresse in millesimi di secondo) dei
tempi di accesso al disco fisso e ciò al fine di verificare, in base ai dati campionari ottenuti, se
esistono differenze significative tra i corrispondenti valori medi di universo µA e µB , ottenendo
i seguenti risultati:
fornitore A
fornitore B
30.0
28.7
29.9
28.6
29.2
29.4
29.8
29.7
30.8
29.9
29.8
30.2
30.4
28.7
28.9
29.4
30.5
30.4
29.7
29.7
Il sistema di ipotesi a conflitto è il seguente:
H0 : µA = µB
H1 : µA #= µB
Desiderando procedere, supponendo che le corrispondenti varianze, pur ignote, possano ritenersi uguali, e ricorrendo alla funzione t.test, si ha:
138
E. D. Isaia, Linguaggio R e applicazioni statistiche
> x<-c(30.0,29.9,29.2,29.8,30.8,29.8,30.4,28.9,30.5,29.7)
> y<-c(28.7,28.6,29.4,29.7,29.9,30.2,28.7,29.4,30.4,29.7)
> t.test(x,y, alternative="two.sided", mu=0,paired = FALSE,
var.equal = TRUE, conf.level = 0.95)
Two Sample t-test
data: x and y
t = 1.5854, df = 18, p-value = 0.1303
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
-0.1398368 0.9998368
sample estimates:
mean of x mean of y
29.90
29.47
Dal momento che il p-value associato al test è maggiore del 10%, i responsabili della Qualità
saranno portati ad accettare l’ipotesi nulla9 e, pertanto, a preferire il fornitore che offre un
prezzo unitario minore.
♥
Due campioni appaiati In tal caso le osservazioni del primo campione non sono
indipendenti da quelle del secondo ed il problema coinvolge, per cosı̀ dire, la nuova v.c.
D = X − Y , mentre l’ipotesi nulla risulta H 0 : µD = µ0 = 0. Specificati gli oggetti,
ad esempio x e y, contenenti le realizzazioni campionarie, si tratterà unicamente di
specificare paired=TRUE.
A commento, osserviamo che se definissimo il nuovo oggetto w<-x-y e ricorressimo
all’istruzione t.test(w), otterremmo ovviamente gli stessi risultati dell’istruzione
t.test(x,y,paired=TRUE).
Esempio 5.3.3 Si supponga che al fine di verificare l’efficacia di un nuovo farmaco anticoagulante, si sono effettuate n = 8 misurazione della concentrazione (in %) di protrombina
su altrettanti pazienti prima e dopo la somministrazione del farmaco, ottenendo i seguenti
risultati:
prima X
dopo Y
0.016
0.014
0.018
0.016
0.023
0.020
0.015
0.012
0.018
0.018
0.015
0.014
0.017
0.018
0.024
0.022
Il sistama di ipotesi che si desidera sottoporre a verifica si presenta:
+
H0 : µX − µY = 0
H1 : µX − µY > 0
Dal momento che l’analisi è stata condotta sui medesimi pazienti, siamo di fronte a due
campioni appaiati (non indipendenti) e pertanto al fine della verifica delle ipotesi poste,
abbiamo:
9
Si osservi che l’intervallo di confidenza [−0.1398368; 0.9998368] contiene lo zero.
139
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> x<-c(0.016,0.018,0.023,0.015,0.018,0.015,0.017,0.024)
> y<-c(0.014,0.016,0.020,0.012,0.018,0.014,0.018,0.022)
> t.test(x,y, alternative="greater", mu=0,paired = TRUE,
var.equal = TRUE, conf.level = 0.95)
Paired t-test
data: x and y
t = 3, df = 7, p-value = 0.009971
alternative hypothesis: true difference in means is greater than 0
95 percent confidence interval:
0.0005527107
NA
sample estimates:
mean of the differences
0.0015
Risultati che indicano come il nuovo farmaco abbia effettivamente potere anti-coagulante. ♥
Osservazione 5.3.1 Desiderando visualizzare o porre in un nuovo oggetto, per successive elaborazioni, un (solo) risultato di interesse, ad esempio il valore della funzione
test, l’intervallo di confidenza, ..., sarà sufficiente aggiungere al comando t.test(...)
il suffisso $ seguito da uno dei seguenti nomi convenzionali: statistic per il valore
della funzione test, p.value per il p−value associato al test, conf.int per l’intervallo
di confidenza.
Potenza e progettazione di test su valori medi - power.t.test
Come si è già sottolineato, due problemi, essenzialmente, sorgono qualora si considerino test di ipotesi statistiche e precisamente:
— valutare il potere discriminatorio della funzione test in corrispondenza ad alcuni
valori di interesse del parametro θ sotto l’ipotesi alternativa;
— individuare la dimensione n del campione casuale sı̀ che essa garantisca prefissate
probabilità di commettere sia l’errore del I tipo che l’errore del II tipo, questa
valutata in corrispondenza di un particolare valore critico θ ∈ Θ 1 .
La risposta al primo quesito è data calcolando la funzione di potenza del test, K (θ),
o equivalentemente la probablità di commettere l’errore del II tipo, β (θ), in corrispondenza ai diversi valori di interesse di θ ∈ Θ 1 .
Quanto al secondo problema, che va sotto il nome di progettazione di un test, si tratta
di risolvere rispetto ad n l’equazione già posta in (5.11) e precisamente:
K(θ ∈ Θ1 ) = 1 − β(θ ∈ Θ1 )
140
E. D. Isaia, Linguaggio R e applicazioni statistiche
una volta fissate le probabilità α e β(θ ∈ Θ 1 ).
Nel caso di verifiche di ipotesi statistiche su un valor medio o sulla differenza tra
due valori medi, i precedenti problemi in R possono essere risolti facendo ricorso alla
funzione power.t.test la cui sintassi completa è:
power.t.test(n=NULL, delta=NULL, power=NULL, sd=1, sig.level=0.05,
type = c("two.sample","one.sample", "paired"),
alternative = c("two.sided", "one.sided"))
dove10 n rappresenta la numerosità del campione casuale, delta la differenza tra le
medie µ1 − µ0 , power la potenza del test in corrispondenza a µ 1 cioè K(µ1 ), sd lo
scarto quadratico medio σ o la sua stima s ed infine sig.level la probabilità α
dell’errore del I tipo.
Il parametro incognito, nel nostro caso power oppure n, deve obbligatoriamente essere
passato alla funzione come NULL. L’output della funzione porge il valore numerico di
tutti i parametri della stessa. Analogamente ad altre funzioni, possiamo visualizzare
ed eventualmente porre in un nuovo oggetto un (solo) risultato di interesse aggiungendo al comando power.t.test(...) il suffisso $ seguito dal nome del parametro
di interesse.
Esempio 5.3.4 L’Esempio 5.2.1, concernente un test unidirezionale a protezione superiore
per un valor medio, proponeva, tra le altre cose, il calcolo della funzione di potenza del
test in corrispondenza all’ipotesi alternativa µ1 = 310, calcolo che venne eseguito applicando
direttamente la (5.8) e ricorrendo alla distribuzione t di Student, con ν = n−1 gradi di libertà
√ µ −µ
e parametro di non centralità n 1 S 0 in corrispondenza a k = 1.6849. In alternativa
avremmo potuto ricorrere alla funzione power.t.test nel seguente modo 11 :
> power.t.test(n=40,power=NULL,delta=10,sd=113.7854,sig.level=0.95,
alternative="one.sided",type="one.sample")
One-sample t test power calculation
n = 40
delta = 10
sd = 113.7854
sig.level = 0.95
power = 0.98578
alternative = one.sided
Si osservi che la probabilità dell’errore del II tipo in corrispondenza a µ1 = 310, ossia β(µ1 )
può essere ottenuta con il comando:
10
11
Perlomeno nel caso di test su un solo valor medio.
Per i dati dell’Esempio 5.2.1 lo scarto quadratico medio vale 113.7854.
141
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> power.t.test(n=40,power=NULL,delta=-10,sd=113.7854,sig.level=0.05,
alternative="one.sided",type="one.sample")
One-sample t test power calculation
n = 40
delta = -10
sd = 113.7854
sig.level = 0.05
power = 0.01422000
alternative = one.sided
Per concludere, si noti il comportamento del comando:
> power.t.test(n=40,power=NULL,delta=delta=10,sd=113.7854,sig.level=0.95
alternative="one.sided",type="one.sample")$power
[1] 0.98578
quantità che, come sempre, potrebbe essere immessa in un nuovo oggetto per successive
elaborazioni.
♥
Esempio 5.3.5 Sia X v.c. distribuita normalmente con parametri µ ignoto e σ 2 stimata,
in base a indagini precedenti, in 225. Desiderando sottoporre a verifica le seguenti ipotesi
statistiche:
+
H0 : µ = µ0 = 100
H1 : µ #= µ0 = 100
si desidera progettare un test che rispetti le seguenti condizioni:
— probabilità dell’errore del I tipo pari al 5%, ossia α = 0.05;
!
!!
— potenza del test in corrispondenza all’ipotesi alternativa µ1 = 120 o µ1 = 80 pari al
!
!!
98%, ovvero K(µ1 ) = K(µ1 ) = 0.98.
Desiderando fare ricorso, in alternativa a quanto fatto a tal riguardo all’Esempio 5.2.3, alla
funzione power.t.test, possiamo porre:
n=NULL,power=0.98,delta=20,sd=sqrt(225),sig.level=0.05,
alternative="two.sided",type="one.sample"
ottenendo:
> power.t.test(n=NULL,power=0.98,delta=20,sd=sqrt(225),sig.level=0.05,
alternative="two.sided",type="one.sample")
One-sample t test power calculation
142
E. D. Isaia, Linguaggio R e applicazioni statistiche
n = 11.20446
delta = 20
sd = 15
sig.level = 0.05
power = 0.98
alternative = two.sided
sı̀ che la numerosità campionaria atta a garantire i vincoli posti sarà n = 12.
♥
Test su due varianze — var.test
Desiderando sottoporre a verifica, sulla base delle realizzazioni di due campioni indi2 ) e Y ∼ N (µ , σ 2 ), l’ipotesi di omoschedapendenti tratti dalle v.c. X ∼ N (µX , σX
Y
Y
2 /σ 2 = 1, contro una delle alternative:
sticità tra le due varianze, cioè H 0 : σX
Y
2
H 1 : σX
/σY2 3= 1
2
H 1 : σX
/σY2 > 1
2
H 1 : σX
/σY2 < 1
a parte la funzione (5.2.1) da noi creata ad hoc, possiamo ricorrere alla funzione
var.test, la cui sintassi è:
var.test(x,y,ratio=1,alternative="less","greater",two.sided",
conf.level=0.95)
con ovvio significato dei parametri che vi compaiono 12 .
Esempio 5.3.6 La verifica di ipotesi sull’uguaglianza tra due valori medi, di cui all’Esempio
2
2
5.3.2, venne condotta presupponendo l’uguaglianza tra le due varianze σA
e σB
. Al fine di
testare tale ipotesi, ricorrendo a var.test, abbiamo:
> x<-c(30.0,29.9,29.2,29.8,30.8,29.8,30.4,28.9,30.5,29.7)
> y<-c(28.7,28.6,29.4,29.7,29.9,30.2,28.7,29.4,30.4,29.7)
> var.test(x,y)
F test to compare two variances
data: x and y
F = 0.8185, num df = 9, denom df = 9, p-value = 0.7702
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
0.203293 3.295101
sample estimates:
ratio of variances
0.8184565
12
Cfr. Osservazione 5.3.2.
143
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Visto che il p-value associato al test è decisamente elevato (77%), siamo propensi ad accettare
l’ipotesi nulla, nonostante il rapporto tra le varianze campionarie sia 0.81846.
♥
Osservazione 5.3.2 Si noti che la funzione var.test prevede l’opzione ratio=k,
2 /σ 2 = k contro le alternative:
con k > 0, consente la verifica dell’ipotesi H 0 : σX
Y
2
H 1 : σX
/σY2 = k
2
H 1 : σX
/σY2 > k
2
H 1 : σX
/σY2 < k
Test su più varianze — bartlett.test
Se consideriamo k > 2 campioni casuali indipendenti, X j ∼ N (µ, σj2 ), ciascuno di
cardinalità nj , con j = 1, 2, . . . , k, la verifica dell’ipotesi di omoschedasticità tra le
varianze e cioè:
H0 : σ12 = σ12 = . . . = σk2
H1 : ∃ (i, j)i$=j σi2 = σj2
può essere effettuata ricorrendo alla funzione bartlett.test.
Dal momento che per ciascun campione la stima della varianza è:
Sj2 =
nj
!
,
-2
1
Xij − X̄j
nj − 1 i=1
il test prende le mosse dalla constatazione che, per ciascun campione, il rapporto:

 1
k
k
n−k
A
1 !
2
(n
−1)
Sj2 (nj − 1)/ 
Sj j 
V =
n − k j=1
j=1
è uguale13 all’unità se e solo se tutte le varianze campionarie sono uguali tra loro,
altrimenti esso assume valori maggiori dell’unità e aumenta via via con l’accrescersi
delle differenze tra le Si2 . Perciò se sotto H0 il rapporto V tenderà ad assumere valori
prossimi a 1, mentre sotto H1 esso assumerà valori tendenzialmente maggiori.
Ora14 , sotto l’ipotesi nulla, una certa funzione del rapporto V , e precisamente:
K2 =
n−k
ln V
Q
dove:
Q=1+
k
!
1
1
1
−
3 (k − 1) j=1 nj − 1 n − k
13
Trattasi, a ben vedere, del rapproto tra la media aritmetica e la media geometrica delle varianze
campionarie pesate con i rispettivi gradi di libertà.
14
Per approfondimenti Bartlett (1937) e, ad esempio, Gartside (1972).
144
E. D. Isaia, Linguaggio R e applicazioni statistiche
descrive una v.c. la cui distribuzione può essere approssimata da quella di Chi-Quadro
con ν = n − k gradi di libertà, viceversa sotto l’ipotesi alternativa essa descrive una
v.c. che tende ad assumere valori sistematicamente maggiori.
Scelto, quindi, un appropriato livello di significatività 1−α, si rifiuterà l’ipotesi di omogeneità delle varianze σi2 se e solo se la variabile test K 2 assume valori appartenenti
alla regione critica [χ2n−k;1−α ; +∞].
Ritornando alla funzione bartlett.test, la sua sintassi è quanto mai semplice,
infatti:
bartlett.test(x, g)
Tuttavia, in linea di massima, occorre osservare che:
— x potrebbe essere un vettore ad elementi numerici corrispondenti alle n osservazioni campionarie; in tal caso è d’obbligo indicare l’oggetto g, di dimensione
uguale a x, i cui elementi indicheranno il campione di appartenenza di ciascun
elemento di x;
— x potrebbe essere una lista i cui k elementi corrispondono alle osservazioni dei
k campioni considerati; in tal caso è sufficiente il comando bartlett.test(x).
Output della funzione sono la funzione test K 2 di Bartlett (statistic), i corrispondenti gradi di libertà (parameter), nonché il p − value (p.value).
Esempio 5.3.7 Si immagini che tre macchinari, A, B e C producano uno stesso componente
meccanico una cui caratteristica di vitale importanza è rappresentata dal diametro. Si supponga, altresı̀ che il diametro del componente meccanico possa essere descritto tramite una
v.c. X ∼ N (µ, σi2 ), i = 1, 2, 3. Onde verificare se i tre macchinari mostrino una uguale variabilità nel corso della produzione, sono stati approntati altrettanti campioni casuali i quali
hanno fornito i seguenti risultati (in mm):
A
30.0
29.9
29.2
29.8
30.8
29.8
30.4
28.9
30.5
29.7
B
26.7
28.6
27.4
28.7
29.9
26.2
27.7
C
28.7
28.6
29.4
29.7
29.9
28.7
29.4
29.7
Definiti i tre oggetti a, b e c che contengono i singoli dati campionari, creiamo la lista abc
che passeremo alla funzione bartlett.test; pertanto:
145
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
>
>
>
>
>
a<-c(30.0,29.9,29.2,29.8,30.8,29.8,30.4,28.9,30.5,29.7)
b<-c(28.7,28.6,29.4,29.7,29.9,28.7,29.4,29.7)
c<-c(26.7,28.6,27.4,28.7,29.9,26.2,27.7)
abc<-list(a,b,c)
bartlett.test(abc)
Bartlett test for homogeneity of variances
data: abc
Bartlett’s K-squared = 6.7661, df = 2, p-value = 0.03394
Essendo il p−value associato alla funzione test decisamente piccolo, siamo propensi a rigettare
l’ipotesi di uguaglianza tra tre le varianze.
La figura (5.1) riporta i diagrammi a “scatola e baffi” dei valori campionari del diametro dei
componenti meccanici, ed è stata ottenuta tramite il comando:
29
28
27
Diametro (mm)
30
> boxplot(abc,main="",xlab="Macchinari",ylab="Diametro (mm)",
col="lightgray",names=c("A","B","C"))
A
B
C
Macchinari
Figura 5.1: Diagrammi a “scatola e baffi” — Esempio 5.3.7
Osserviamo che avremmo effettuare il test organizzando i dati campionari nel seguente modo:
146
E. D. Isaia, Linguaggio R e applicazioni statistiche
> dati<-c(30.0,29.9,29.2,29.8,30.8,29.8,30.4,28.9,30.5,29.7,28.7,28.6,
29.4,29.7,29.9,28.7,29.4,29.7,26.7,28.6,27.4,28.7,29.9,26.2,27.7)
> gruppi<-c(rep(1,10),rep(2,8),rep(3,7))
> bartlett.test(dati,gruppi)
Bartlett test for homogeneity of variances
data: dati and gruppi
Bartlett’s K-squared = 6.7661, df = 2, p-value = 0.03394
ottenendo, coerentemente, lo stesso risultato.
♥
Il test di Bartlett trova applicazione sopratutto nell’ambito dell’Analisi delal Varianza
(ANOVA) e in generale nello studio dei modelii lineari.
Test esatto su una proporzione — binom.test
Ricorrendo alla funzione binom.test possiamo sottoporre a verifica l’ipotesi statistica
H0 : π = π0 contro una delle alternative:
H1 : π 3= π0
H1 : π < π0
H1 : π > π0
(
sulla base15 delle realizzazioni della funzione test T = n −1 ni=1 Xi , la quale, sotto
l’ipotesi nulla, ha distribuzione binomiale di parametri n, π 0 .
Senza entrare in dettagli, la sintassi per accedere a tale funzione è:
binom.test(x, n, p = 0.5, alternative = c("two.sided", "less",
"greater"), conf.level = 0.95)
dove x indica il numero di Successi osservati in n prove indipendenti di un esperimento
casuale. L’utente, come sempre, può specificare l’ipotesi alternativa nonché il livello
di confidenza richiesto. Si osservi che la situazione di default prevede π 0 = 0.5.
Esempio 5.3.8 Da precedenti indagini la proporzione di neonate affette da displasia all’anca
era approssimativamente pari al 3%. In base ad una recente indagine condotta su un campione
casuale di 120 neonate solo tre sono risultate affette da displasia all’anca. Possiamo affermare
la proporzione sia dinimuita?
Il sistema di ipotesi a conflitto risulta:
+
H0 : π = π0 = 0.03
H1 : π < π0
Ricorrendo alla funzione binom.test, abbiamo:
15
Si ricordi quanto detto a tal proposito alla fine del paragrafo5.1 e riassunto dalla Funzione 5.1.4
e dall’Esempio 5.1.5.
147
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> binom.test(3,120,p=0.03,alternative="less",conf.level=0.95)
Exact binomial test
data: 3 and 120
number of successes = 3, number of trials = 120, p-value = 0.5133
alternative hypothesis: true probability of success is less than 0.03
95 percent confidence interval:
0.00000000 0.06333852
sample estimates:
probability of success
0.025
Essendo decisamente elevato il p−value associato al test, siamo propensi ad accettare l’ipotesi
nulla e concludere quindi che la proporzione di neonate affette da displasia all’anca non sia
mutata nel corso del tempo.
♥
Osservazione 5.3.3 Qualora si desideri effettuare una verifica di ipotesi sulla differenza tra due proporzioni, sulla base di due campioni indipendenti di numerosità
elevata, si può ricorrere alla funzione t.test.
Esempio 5.3.9 Da un indagine condotta su un campione casuale di 200 individui adulti, di
cui 100 di sesso femminile e i restanti di sesso maschile, risulta che il 75% dei maschi fuma,
mentre le fumatrici sono il 55%. Si desidera sottoporre a verifica il seguente sistema di ipotesi
statistiche:
+
H0 : πmaschi = πf emmine
H1 : πmaschi > πf emmine
Ricorrendo alla funzione t.test, occorre dapprima creare i due vettori, maschi e femmine,
delle osservazioni campionarie; tali vettori conterranno 100 elementi con opportuna alternanza
di 0 (non fumatore/fumatrice) e di 1 (fumatore/fumatrice). Ciò premessso:
> maschi<-c(rep(1,75),rep(0,25))
> femmine<-c(rep(1,55),rep(0,45))
> t.test(maschi,femmine, alternative="two.sided", mu=0,
paired = FALSE, var.equal = TRUE, conf.level = 0.95)
Two Sample t-test
data: maschi and femmine
t = 3.0172, df = 198, p-value = 0.002886
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
0.06928128 0.33071872
sample estimates:
mean of x mean of y
0.75
0.55
148
E. D. Isaia, Linguaggio R e applicazioni statistiche
Essendo decisamente piccolo il p − value associato al test, siamo propensi a rigettare l’ipotesi
di uguaglianza tra le due proporzioni.
♥
Test sul coefficiente di correlazione lineare — cor.test
Desiderando verificare se due due campioni casuali, X e Y di egual cardinalità n,
2 ) e Y ∼ N (µ , σ 2 ) linearmente indiprovengono da altrettante v.c. X ∼ N (µ X , σX
Y
Y
16
pendenti , possiamo effettuare un test teso a verificare se il coefficiente di correlazione
lineare ρ tra le v.c. X e Y possa ritenersi nullo oppure no. In sostanza, si tratta di
sottoporre a verifica le seguenti ipotesi statistiche:
+
H 0 : ρ = ρ0 = 0
H1 : ρ 3= ρ0 = 0
In tali situazioni abitualmente si ricorre alla funzione test corrispondente al coefficiente
di correlazione campionario r del Pearson, definito come:
r=
SX,Y
SX SY
o, meglio, alla sua trasformata:
r √
n−2
1 − r2
che sotto H0 viene a possedere distribuzione t di Student con ν = n−2 gradi di libertà.
Sotto tali condizioni si possono applicare le tecniche generali esposte al paragrafo (5.2).
In R possiamo procedere ad un siffatto test di ipotesi ricorrendo alla particolare
funzione cor.test, la quale, bene qui sottolinearlo, prevede anche altri tipi di test
non parametrici. Nel seguito, tuttavia, considereremo unicamente il caso di test
parametrico basato sul rapporto di correlazione del Pearson 17 . Sotto tale profilo, la
sintassi della funzione in esame si riduce a:
cor.test(x, y)
dove, ovviamente, x e y sono due vettori ad elementi numerici e di egual dimensione,
cioè tali che length(x)=length(y).
Output essenziali sono la funzione test r di Pearson (statistic), i corrispondenti
gradi di libertà (parameter), nonché il p − value (p.value).
16
Il che equivale a chiedersi se essi siano estratti da una v.c. Normale bivariata a componenti
linearmente indipendenti.
17
Che d’altronde corrisponde alla situazione di default.
149
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Esempio 5.3.10 Si immagini di avere rilevato, su un campione di n = 10 autovetture mediopiccole ad alimentazione a benzina e trazione anteriore, la potenza espressa in CV-Din e la
velocità massima dichiarata espressa in km/h, ottenendo i seguenti risultati:
Potenza (CV-Din)
45
54
45
50
60
65
70
54
70
60
Velocità (km/h)
135
145
137
140
150
140
160
145
150
150
Organizzate, per comodità, le osservazioni campionarie nel data frame dati, la figura (5.2)
porge alcune informazioni circa la dipendenza tra le variabili in esame.
140
145
150
155
160
70
135
55
45
50
0.8
60
65
CV.Din
135
145
155
Vel.max
45
50
55
60
65
70
Figura 5.2: Correlazione tra velocità massima e potenza — Esempio 5.3.10
I comandi atti allo scopo sono:
150
E. D. Isaia, Linguaggio R e applicazioni statistiche
>
>
>
>
x<-cbind(c(45, 54, 45, 50, 60, 65, 70, 54, 70, 60))
y<-cbind(c(135, 145, 137, 140, 150, 140, 160, 145, 150, 150))
dati<-data.frame(CV.Din=x,Vel.max=y)
pairs(dati,panel=panel.fit,diag.panel=panel.hist,
upper.panel=panel.cor)
Desiderando sottoporre a verifica le seguenti ipotesi statistiche:
+
H0 : ρ = ρ 0 = 0
H1 : ρ #= ρ0 = 0
ricorrendo alla funzione cor.test avremo:
> attach(dati)
> cor.test(CV.Din,Vel.max)
Pearson’s product-moment correlation
data: CV.Din and Vel.max
t = 3.6893, df = 8, p-value = 0.006137
alternative hypothesis: true correlation is not equal to 0
sample estimates:
cor
0.7936084
> detach(dati)
ed evidentemente saremo portati al rigetto di H0 .
♥
È bene notare che a volte si è interessati a verificare, sulla base dei valori campionari
osservati, l’ipotesi che il coefficiente di correlazione della popolazione sia uguale ad un
valore specificato non nullo, poniamo ρ 0 3= 0. In altri termini si desidera sottoporre a
vericfica le le ipotesi statistiche:
+
H0 : ρ = ρ0 3= 0
H1 : ρ 3= ρ0
In tal caso, si può ricorre alla funzione test:
z=
√
n−3
+
0.5 ln
)
*
)
1+r
1 + ρ0
− 0.5 ln
1−r
1 − ρ0
*D
la quale sotto H0 tende a distribuirsi, perlomeno asintoticamente, secondo una N (0, 1).
Se tale è il caso, allora possiamo pensare di implementare una funzione ad hoc che
potrebbe presentarsi come:
151
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
1
2
3
4
5
6
7
8
9
Funzione 5.3.1
rho.test<-function(rho,x,y)
{
covar(x,y,print=F)
r<-rxy.out
n<-length(!is.na(x))
z<-(sqrt(n-3))*(0.5*log((r+1)/(1-r))-0.5*log((rho+1)/(1-rho)))
pval<-2*pnorm(-abs(z))
cat("r =",r,"rho =",rho,"p-value=",pval,"\n")
}
Test di indipendenza chisq.test
Dedichiamo questo paragrafo alla presentazione di un particolare test di ipotesi statistiche che si differenzia dai precedenti per il fatto che non viene ipotizzata alcuna
forma per la densità della v.c. da cui viene tratto il campione casuale. Tali test
vengono abitualmente detti test “non parametrici”
Si immagini che due caratteri possano essere descritti in modo congiunto mediante la
v.c. bivariata (X, Y ); il problema che tenteremo di risolvere è verificare, sulla base
delle realizzazioni di due campioni di ugual numerosità X e Y tratti da (X, Y ), se la
v.c. in esame è a componenti stocasticamente indipendenti, in simboli X ⊥ Y .
In sostanza si tratta di verificare il seguente sistema di ipotesi statistiche:
+
H0 : X ⊥ Y
H1 : X 3⊥ Y
(5.12)
Abitualmente le realizzazioni campionarie x e y vengono organizzate in una tabella
a doppia entrata di dimensione r × s, dove r indica il numero delle modalità di x e
s il numero delle modalità di y, che riporta il numero delle unità campionarie che
presentano al contempo modalità i di X e j di Y , cioè le frequenze congiunte n ij , con
i = 1, 2, . . . , r e j = 1, 2, . . . , s
Al fine della verifica del sistema di ipotesi (5.12) si ricorre alla funzione test, dovuta
al Pearson:
X2 =
r !
s
!
(nij − n̂ij )2
i=1 j=1
(5.13)
n̂2ij
dove n̂ij rappresentano le frequenze congiunte che ci si attenderebbe osservare nel
caso di indipendenza stocastica18 tra le componenti la v.c. doppia (X, Y ).
18
E cioè, com’è facile accertare: n̂ij =
proposito si veda anche l’Esempio 3.2.3.
(r
i=1
nij
152
(s
j=1
nij /
(r
i=1
(s
j=1
nij = n.j ni. /n. A tal
E. D. Isaia, Linguaggio R e applicazioni statistiche
Sotto H0 , la funzione test (5.13) è distribuita approssimativamente socondo una ChiQuadro con (r − 1) (s − 1) gradi di libertà. Il test tenderà, dunque, ad accettare
l’ipotesi nulla se e solo se il valore osservato della (5.13) è non maggiore di q 1−α , dove,
coerentemente con quanto precedentemente esposto:
P [X 2 ≤ q1−α ; H0 ] ≈ 1 − α
Al fine della verifica del sistema di ipotesi (5.12), organizzate le frequenze osservate
in una martrice, diciamo x, di dimensione r × s, possiamo ricorrere alla funzione
chisq.test ed impartire il comando:
chisq.test(x, correct = FALSE)
Senza entrare in dettagli, osserviamo che ponendo correct=TRUE, che rappresenta la
situazione di default, la funzione provvede in modo automatico ad applicare correzione
dello Yates, cioè ricorre alla funzione test:
X2 =
r !
s
!
(nij − n̂ij − 0.5)2
i=1 j=1
n̂2ij
qualora si operi su campioni poco numerosi.
Esempio 5.3.11 Un campione casuale di 200 individui adulti è stato classificato in base al
sesso e l’occupazione, ottenendo la seguente ditribuzione congiunta di frequenze:
Occupazione ↓ Sesso →
Occupato
Disoccupato
Maschio
100
20
Femmina
50
30
Al fine di verificare se vi sia una relazione di dipendeza tra il sesso e l’occupazione, ricorriamo
al test chisq.test():
> x<-matrix(c(100,20,50,30),2,2)
> chisq.test(x,correct=FALSE)
Pearson’s Chi-squared test
data: x
X-squared = 11.1111, df = 1, p-value = 0.0008581
Dal momento che il p−value associato al test è decisamente piccolo, saremo portati a rigettare
l’ipotesi di indipendenza tra i caratteri considerati.
♥
Esempio 5.3.12 Un dado viene lanciato 1000 volte dando luogo alla seguente distribuzione
empirica:
153
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Punteggi
Frequenze
xi
ni
1
142
2
186
3
157
4
177
5
176
6
162
Possiamo pensare che il dado sia equilibrato?
Il problema può essere risolto confrontando la distribuzione delle frequenze empiriche con la
distribuzione delle frequenze che ci aspetteremo di osservare qualora il dado fosse regolare,
cioè sotto l’ipotesi H0 : ni = 1000/6 = 166.6667. Ricorriamo, pertanto, ad una verifica di
ipotesi basata sulla funzione test (5.13).
> dadi<-sample(c(1:6), 1000, replace = TRUE)
> table(dadi)
1
2
3
4
5
6
142 186 157 177 176 162
> chisq.test(table(dadi))
Chi-squared test for given probabilities
data: table(dadi)
X-squared = 7.748, df = 5, p-value = 0.1707
In sostanza possiamo accettare l’ipotesi che il dado sia equilibrato. Si osservi che, se è il caso,
possiamo passare in modo diretto i valori delle frequenze teoriche alla funzione chisq.test
con l’opzione p=(...), che per default è rep(1/length(x), length(x)).
♥
154
Capitolo 6
Alcune note sui modelli lineari
Nel seguito vedremo come sia possibile affrontare e risolvere in R alcuni problemi che
concernono modelli statistici lineari e, in particolare, ci occuperemo, seppur a grandi
linee data la vastità dell’argomento, dell’analisi della regressione e dell’analisi della
varianza.
Diciamo subito che non ci occuperemo della costruzione di routine di caclolo ad hoc,
ma piuttosto illustreremo come sfruttare le principali funzioni presenti in R e raccolte
nella libreria base che in linea di massima si basano sui comandi lm, acronimo di
“linear model”, e aov, acronimo di “analysis of variance”.
6.1
La regressione lineare semplice: il modello teorico
Se consideriamo una v.c. doppia (X, Y ) a componenti non indipendenti, è chiaro che
la conoscenza del valore assunto da X viene a modificare il nostro grado di incertezza
circa la realizzazione di Y ; in generale tale incertezza viene a diminuire, dal momento
che la distribuzione di Y condizionata all’evento X = x viene a possedere in media
una varianza più piccola1 della varianza di Y .
In tutte quelle situazioni in cui si può ipotizzare che un fenomeno, descrivibile mediante la v.c. X abitualmente detta variabile esplicativa o predittiva, possa essere
impiegato per “spiegare” quello descritto dalla v.c. Y , detta variabile variabile risposta, si è portati a ricercare un legame funzionale del tipo Y ∗ = f (X) che possa offrire
una previsione per Y tramite X; in particolare si tratta di individuare una funzione f
tale che IE[Y − f (X)] = 0 ed al contempo sia il più vicino possibile ad Y ad esempio
in media quadratica, ovvero minimizzi IE[(Y − f (X)) 2 ].
Dalla teoria è noto che tali condizioni sono soddisfatte ponendo f (X) = IE[Y |X].
Tale funzione, che ad una determinazione x di X associa IE[(Y |X = x], viene detta
funzione di regressione di Y rispetto a X e, fissato un sistema di riferimento ortogonale
cartesiano, il corrispondente grafico viene indicato quale curva di regressione di Y
1
Il fatto che IE[V ar(Y |X)] ≤ V ar[Y ] discende dal teorema della Scissione della Varianza Totale.
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
rispetto a X. La bontà dell’approssimazione di Y mediante IE[Y |X], lo ricordiamo,
viene misurata attraverso il rapporto di correlazione di Pearson, definto come:
ηY2 |X =
V ar[IE[Y |X]]
V ar[Y ]
Alla luce di tali considerazioni, possiamo, dunque, porre:
Y = IE[Y |X] + -
(6.1)
dove - = Y − IE[Y |X] rappresenta il residuo della regressione o componente di disturbo; più in particolare si può dimostrare che trattasi di una v.c. non correlata nè con
X nè con IE[Y |X], per la quale si ha IE[-] = 0 e V ar[-] = V ar[Y ] (1 − η Y2 |X ).
6.2
La regressione lineare
Sorge naturale, a questo punto, il problema della scelta del legame funzionale f (X); a
tal proposito, perlomeno dal punto di vista applicativo, notevole importanza 2 riveste
il caso in cui per esso si scelga un polinomio di primo grado, cioè si ponga:
IE[Y |X] = α + β X
sı̀ che la (6.1) diviene:
Y = α+βX +-
(6.2)
Sotto tale ipotesi di lavoro, è facile dedurre:
α = IE[Y ] − β IE[X]
β=
Cov(X, Y )
σY
=ρ
V ar[X]
σX
Ciò premesso, la funzione di regressione di Y rispetto a X viene ad assumere la forma:
σY
Y = IE[Y ] + ρ
(X − IE[X]) + (6.3)
σX
e viene abitualmente detta retta di regressione di Y rispetto a X.
Se si considera la varianza di ambo i membri della (6.3): V ar[Y ] = ρ 2 V ar[Y ] +V ar[-],
segue:
V ar[-] = V ar[Y ] (1 − ρ2 )
(6.4)
a riprova che nel caso di regressione lineare: η Y2 |X = ρ2 .
2
Si osservi che qualora la v.c. doppia (X, Y ) possegga distribuzione normale bivariata, allora
−2
IE[Y |X = µY + σXY σX
(X − µX ), dove σXY = Cov(X, Y ).
156
E. D. Isaia, Linguaggio R e applicazioni statistiche
6.2.1
Stima della retta di regressione in base ai valori campionari
Supponendo ora vera l’ipoesi IE[Y |X] = α + β X, e dispondendo di un campione casuale (X, Y) = ((X1 , Y1 ), (X2 , Y2 ), . . . , (Xn , Yn )) di dimensione n > 2 tratto dalla v.c.
bivariata (X, Y ), il problema che ci si pone, perlomeno dal punto di vista statistico, è
quello della stima dei parametri α e β nonché della varianza del termine di disturbo.
Data la n-pla campionaria (xi , yi )i=1,2,...,n , si tratterà, dunque, di individuare i parametri della retta, di equazione poniamo ŷ = a + b x, interpolante la “nuvola di punti”
di coordinate (xi , yi ); il ricorso al metodo dei minimi quadrati comporta, com’è noto,
la minimizzazione della funzione:
F (a, b) =
n
!
i=1
(yi − ŷi )2 =
n
!
i=1
(yi − a − b xi )2
∂F
La condizione ∂∂ F
a = ∂ b = 0, porge il sistema delle “equazioni normali”:
 (n
 i=1 (yi − a − b xi ) = 0
 (n
i=1 (yi
(6.5)
− a − b x i ) xi = 0
da cui facilmente:
b=
!n
i=1
(yi − ȳ) (xi − x̄)
!n
(xi − x̄)
2
i=1
=
Cov(x, y)
sy
=r
2
sx
sx
a = ȳ − b x̄
(6.6)
(6.7)
s
e quindi ŷ = ȳ + r sy (x − x̄) viene a rappresentare la versione empirica della retta di
x
regressione posta in (6.3).
Chiaramente, al variare della n-pla campionaria (x i , yi ), le grandezze x̄, ȳ, s2x , s2y ,
r, ŷ, a e b altro non sono che realizzazioni di altrettante v.c.; queste ultime due in
particolare sono determinazioni, rispettivamente, degli stimatori A e B definiti:
A = Ȳ − B X̄
B=
!n
i=1
(6.8)
(Yi − Ȳ ) (Xi − X̄)
!n
i=1
(6.9)
(Xi − X̄)2
157
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Desiderando procedere, si può dimostrare che trattasi 3 di stimatori corretti, nel senso
che IE[A] = α e IE[B] = β, con varianza4 , fissate le realizzazioni xi delle n v.c. Xi :
V ar [B] = !n
i=1

σ2
(6.10)
(xi − x̄)2

1
σ2
x̄2
=
V ar [A] = σ 2  + !n
+ x̄2 V ar [B]
n
n
(xi − x̄)2
(6.11)
i=1
Senza voler verificare la veridicità di tale affermazione, ci limitiamo ad osservare
che le dimostrazioni partono dalla semplice considerazione che il valore atteso del
valore atteso di uno stimatore condizionatamente alle realizzazioni x i delle n v.c. Xi
corrisponde al valor medio dello stimatore stesso.
Dal momento poi che IE[Y |X = x] = α + β x, possiamo affermare che ŷ = a + b x è
una stima corretta di α + β x. Quanto alla varianza dello stimatore Ŷ , avremo:

E F

(x − x̄)
1

V ar Ŷ = σ 2  + !n
n
(xi − x̄)2
2
(6.12)
i=1
È bene osservare che il parametro incognito σ 2 , che compare in modo esplicito nelle
(6.10), (6.11) e (6.12), altro non è che la varianza delle Y i , date le realizzazioni xi
delle v.c. Xi , cioè:
σ 2 = V ar[Yi |Xi = xi ] = V ar[-]
Quale sua stima sorge spontaneo ricorrere alla varianza campionaria dei residui:
Se2
=
!n
i=1
(Yi − Ŷi )2
n−1
tuttavia tale stimatore non risulta corretto. Infatti si può dimostrare che:
n
!
i=1
(Yi − Ŷi )2 = σ 2
n
!
i=1
(1 − hi ) = σ 2 (n −
n
!
i=1
hi ) = σ 2 (n − 2)
(6.13)
dove, per X = xi fissato:
hi =
3
!n
i=1
n
x2i − 2 xi
!n
i=1
!n
i=1
!
n
x2i − (
xi + n x2i
i=1
xi )2
(6.14)
In verità essi risultano stimatori corretti a varianza minima. Per inciso tali stimatori non risultano
tra loro stocasticamente inipendenti.
4
E ciò indipendentemente dalla legge di distribuzione delle v.c. coinvolte.
158
E. D. Isaia, Linguaggio R e applicazioni statistiche
e quindi stimatore corretto di σ 2 risulta:
S2 =
6.2.2
!n
i=1
(Yi − Ŷi )2
(6.15)
n−2
Verifiche di ipotesi circa i parametri della retta di regressione
I risultati sin qui proposti prendevano le mosse dalla semplice considerazione che la
funzione di regressione di Y rispetto a X fosse esprimibile mediante un polinomio di
primo grado, cioè IE[Y |X] = α + β X; in sostanza senza fare alcuna ipotesi circa le
distribuzioni delle v.c. coinvolte.
,
Ipotizzando, ora, che la v.c.
- abbia distribuzione
N 0, σ 2 , allora la v.c. Y |X = x
,
segue una distribuzione N α + β x, σ 2 e pertanto:


1
x̄2
)
A ∼ N β, σ 2 ( + !n
n
(xi − x̄)2
i=1

B ∼ N β, !n
σ2
i=1
(xi − x̄)2

Ŷ ∼ N α + β x, σ 2 (



1
(x − x̄)
+ !n
)
n
(xi − x̄)2
2
i=1
(n − 2) S 2
viene a possedere distribuzione χ2n−2 ; inoltre, si dimostra
σ2
che essa è indipendente da Ȳ , A e B.
Sotto tali ipotesi, dunque, le v.c. (statistiche test):
mentre la v.c.
Ta =
A−α
G
H
H1
S I + !n
n
Tb =
i=1
(xi − x̄)2
B−β
G
H
H
S I !n
i=1
(6.16)
x̄2
1
=
(B − β) SX √
n−1
S
(6.17)
(xi − x̄)2
vengono entrambe a possedere distribuzione t di Student con n − 2 gradi di libertà.
159
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Tali considerazioni consentono di costruire di intervalli di confidenza o effettuare verifiche di ipotesi sui parametri del modello. A tal proposito, le ipotesi che abitualmente
vengono poste a confronto sono del tipo:
+
+
H0 : α = 0
H1 : α 3= 0
(6.18)
H0 : β = 0
H1 : β 3= 0
(6.19)
Per completezza, presentiamo un test che, basandosi sull’analisi della varianza della
regressione, offre indicazioni circa la la bontà di adattamento dei dati alla retta di
regressione.
Dal momento che la devianza (totale) di Y può essere scissa come:
n
!
i=1
J
(Yi − Ȳ )2 =
abbiamo:
KL
M
SST ot
n
!
i=1
J
(Yi − Ŷ )2 +
KL
SSE
M
n
!
i=1
J
(Ŷi − Ȳ )2
KL
SSR
(6.20)
M
— per cose ormai note:
n
!
i=1
(Yi − Ŷ )2
σ2
=
SSE
∼ χ2n−2
σ2
— se, e solo se, è vera l’ipotesi H 0 : β = 0:
n
!
i=1
(Yi − Ȳ )2
σ
2
=
SST ot
∼ χ2n−1
2
σ
ed inoltre5 :
n
!
i=1
5
(Ŷi − Ȳ )2
σ
2
=
SSR
=
σ2
n
!
i=1
Si ricordi che per le ipotesi di lavoro σ
una N (0, 1).
−2
B (Xi − X̄)2
σ
2
(n
i=1
160
∼ χ21
(B − β) (Xi − X̄)2 ∼ χ21 in quanto quadrato di
E. D. Isaia, Linguaggio R e applicazioni statistiche
(
(
n
n
2
2
Osservando infine, l’indipendenza tra le v.c.
i=1 (Yi − Ŷ ) e
i=1 (Ŷi − Ȳ ) , vera
l’ipotesi H0 : β = 0, il rapporto tra le devianze SS R e SSE ciascuna delle quali divisa
per i rispettivi gradi di libertà, cioè:
(n − 2)
n
!
i=1
n
!
i=1
(Ŷi − Ȳ )2
(Yi − Ŷ )
2
=
(n − 2) SSR
SSE
(6.21)
viene a possedere6 distribuzione F di Snedecor con un grado di libertà a numeratore
ed n − 2 gradi di libertà a denominatore.
L’adeguatezza del modello di regressione può pertanto essere verificata in base al
p − value associato al valore di F sperimentale. Valori di F sperimentale prossimi
allo zero possono essere spiegati da elevati valori di σ 2 oppure possono suggerire che
il modello non spieghi in modo esaustivo il comportamento della variabile risposta.
Osservazione 6.2.1 Nel caso di modello di regressione lineare, il test di adeguatezza
appena illustrato viene a corrispondere al test circa il coefficiente di correlazione
lineare:
+
H0 : ρ = 0
H1 : ρ 3= 0
(6.22)
Infatti, nel caso in esame, se osserviamo che:
4
6
n−1
1 !n
(Yi − Ŷ )2 = 1 − R2 SY2
i=1
n
n
il rapporto posto in (6.21) può essere riscritto come:
(n − 2)
R2
1 − R2
Tale v.c., sotto l’ipotesi nulla ρ = 0 viene a possedere distribuzione t di Student con
(n − 2) gadi di libertà; ora, per cose note, risulta (T n−2 )2 = F (1; n − 2).
6
In virtù del Teorema di Cochran.
161
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
6.2.3
Alcune considerazioni circa la previsione
Si immagini di volere prevedere, tramite il modello di regressione, il valore della
variabile risposta Y in corrispondenza ad un’ulteriore determinazione di interesse x 0
di X non osservata. Una sua stima puntuale, Ŷ0 , la si ottiene semplicemente ponendo
Ŷ0 = a + b x0 , ma per cose ovvie essa di per sé è di scarso interesse. Nel seguito si
vedrà come sia possibile pervenire alla costruzione di un “intervallo di previsione” per
per la stima stessa.
Da quanto esposto al paragrafo precedente, le v.c. Ŷ0 e Y |X = x0 posseggono
distribuzione Normale entrambe con valor medio α + β x 0 e varianza rispettivamente:


(x0 − x̄)2 
1
V ar[Ŷ0 ] = σ 2  + !n
n
(xi − x̄)2
i=1
e:
V ar[Y |X = x0 ] = σ 2
Ora, mentre Ŷ0 dipende dalla n-pla di valori osservati x 1 , x2 , . . . , xn , Y |X = x0 dipende unicamente dal valore “futuro” x0 ; quindi, supponendo indipendenti le realizzazioni
della v.c. disturbo -, possiamo affermare l’indipendenza tra le v.c. Ŷ0 e Y |X = x0 .
Segue, dunque, che la v.c. (Y |X = x0 ) − Ŷ0 possiede distribuzione Normale con valor
medio nullo e varianza:


(x0 − x̄)2 
1
V ar[(Y |X = x0 ) − Ŷ0 ] = σ 2 1 + + !n
n
(xi − x̄)2
i=1
Si osservi come la varianza dell’errore di previsione dipende da due fattori e precisamente: dalla varianza intrinseca della v.c. Y |X = x 0 , cioè σ 2 , e dalla variabilità
indotta dalle stime dei parametri α e β del modello di regressione, che contrariamente
alla prima può essere ridotta aumentando la dimensione del campione.
Da quanto sopra, la v.c. standardizzata:
(Y |X = x0 ) − Ŷ0
G
H
H
1
(x0 − x̄)2
S I1 + + !n
n
i=1
(xi − x̄)2
viene a possedere distribuzione t di Student con n − 2 gradi di libertà, per cui
l’intervallo di previsione per la stima ŷ 0 , sarà:
G
H
H
1
(x0 − x̄)2
ŷ0 ± n−2 t1−α/2 s I1 + + !n
n
i=1
(xi − x̄)2
162
(6.23)
E. D. Isaia, Linguaggio R e applicazioni statistiche
Si noti come l’intervallo di previsione sia più ampio, a parità di α, del corrispondente
intervallo di confidenza per ŷ i :
G
H
H1
(xi − x̄)2
ŷi ± n−2 t1−α/2 s I + !n
n
6.2.4
i=1
(xi − x̄)2
(6.24)
Alcune considerazioni sull’analisi dei residui
L’analisi dei residui yi − ŷi riveste un ruolo non secondario in quanto essa può essere
di aiuto per
(a) la verifica di alcune ipotesi di base, quali la linearità, l’omoshedasticità, la
normalità degli errori stessi, ...;
(b) l’individuazione di eventuali valori anomali e/o di osservazioni che hanno un
peso determinante nel processo di stima del modello di regressione.
Generalmente e sicuramente in prima battuta, tale analisi viene condotta per via
empirica ricorrendo ai seguenti diagrammi a dispersione:
— residui yi − ŷi in funzione dei valori teorici ŷ i ;
— residui standardizzati7
s
yi − ŷi
>
1 − hi
in funzione dei valori teorici ŷ i ;
— quantili empirici dei residui in funzione dei quantili teorici di una N (0, 1).
i quali non devono lasciare trasparire alcuna tendenza.
Quanto al precedente punto (b), oltre all’analisi grafica testé proposta, può essere di
aiuto lo studio delle cosidette “distanze di Cook” le quali (Cook, Weisberg 1982) consentono di individuare l’influenza esercitata sulla stima del coefficiente di regressione
β da ciascuna osservazione xi . Senza entrare in dettagli, osserviamo che, per ciascun
xi , esse possono essere definite:
di =
2
yi − ŷi
s (1 − hi )
32
hi
2
(6.25)
Dal punto di vista pratico, un valore di di prossimo o maggiore dell’unità indica
un’influenza anormale sulla stima.
Si tenga presente, per concludere, che ad un residuo elevato può corrispondere un
valore anomalo, tuttavia un’osservazione anomala può presentare un residuo piccolo
o adirittura nullo. Per approfondimenti sull’argomento si confronti, ad esempio, il
testo di Belsley, Kuh e Welsch (1980).
7
A tal proposito si ricordi la (6.13) e la (6.14).
163
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
6.3
La regressione lineare semplice in R
Desiderando effettuare un’analisi della regressione lineare in R, cosı̀ come delineata nei
paragrafi precedenti, si può ricorrere alla funzione lm(), il cui output è un oggetto con
struttura di lista, i cui elementi possono essere visualizzati e/o acquisiti per successive
elaboarazioni nel corso di una seduta di lavoro. Dal momento che trattasi di una
funzione assai flessibile e ricca di una vasta gamma di opzioni, nel seguito introdurremo
dapprima i comandi di base, rimandando ai paragrafi successivi la descrizione di alcune
opzioni di interesse.
6.3.1
La funzione lm(): definizione del modello di regressione
Raccolte le osservazioni campionarie (x i , yi )i=1,2,...,n nei due oggetti x e y, il primo
passo consiste nella definizione del modello di regressione; per il modello lineare posto
in (6.2), è sufficiente il comando:
> lm(formula = y~x)
o più semplicemente:
> lm(y~x)
In seguito a tale comando, R visualizza, per default, le stime dei parametri α e β del
modello e ciò in accordo alla (6.7) e (6.6).
Esempio 6.3.1 Com’è noto la concentrazione di ozono (Y ), espressa in mg per m 3 , nelle
grandi aree metropolitane dipende, oltre che da altri fattori, in gran misura dalla temperatura
ambientale (X). I dati che seguono riguardano un campione di n = 26 osservazioni, tratte
casualmente da una banca dati delle misurazioni registrate da una centralina di controllo in
altrettanti giorni feriali dei mesi di giugno e luglio alle ore 12.00 nei pressi di un’importante
crocevia:
xi
yi
xi
yi
22
9
28
28
24
23
29
35
25
21
30
44
25
22
30
73
26
31
30
78
26
44
31
66
26
45
32
89
26
59
32
110
27
9
32
122
27
39
34
85
27
65
34
118
27
128
36
76
28
16
36
84
Posto che la relazione che lega la concentrazione di ozono e la temperatura ambientale possa
essere riassumibile dal modello lineare Y = α + β X, la stima dei parametri ci viene offerta
dalle istruzioni:
> x<-c(22,24,25,25,26,26,26,26,27,27,27,27,28,
28,29,30,30,30,31,32,32,32,34,34,36,36)
> y<-c(9,23,21,22,31,44,45,59,9,39,65,128,16,
164
E. D. Isaia, Linguaggio R e applicazioni statistiche
28,35,44,73,78,66,89,110,122,85,118,76,84)
> lm(y~x)
Call:
lm(formula = y ~ x)
Coefficients:
(Intercept)
-131.332
x
6.578
sı̀ che la stima della retta di regressione diviene ŷi = −131.332 + 6.578 xi .
♥
A proposito della fase di definizione del modello di regressione lineare, è bene tenere a
mente che, posti x e y gli oggetti contenenti le n osservazioni campionarie, le istruzioni:
> lm(y~x)
> lm(y~+1+x)
sono equivalenti e definiscono entrambe il modello di regressione Y = α+ β X, mentre
le istruzioni:
> lm(y~0+x)
> lm(y~-1+x)
> lm(y~x-1)
definiscono il modello Y = β X, privo quindi della costante α.
Concludiamo osservando che, anche se non necessario, è tuttavia buona norma:
— strutturare le osservazioni campionarie sottoforma di data frame e impartire
successivamente il comando lm(formula=...,data=data.frame); in tal caso, i
dati sono disponibili senza dover ricorrere all’istruzione attach();
— introdurre un nuovo oggetto, con struttura di formula, che servirà appunto
a definire il modello di regresione lineare di interesse. Ad esempio valgano le
istruzioni:
> x<-c(...)
> y<-c(...)
> dati<-data.frame(Risposta=y,Predittore=x)
> formulayx<-as.formula(paste(names(dati)[1],"~",names(dati)[2]))
> formulayx
Risposta ~ Predittore
165
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
— definire un nuovo oggetto che conterrà sia il modello che i risultati dell’analisi di regressione richiesta; a tal fine sarà sufficiente, ad esempio, l’istruzione
modello.analisi.1<-lm(formula=...,data=...). L’espressione del modello
di regressione in esame può essere visualizzata in qualsiasi istante con l’istruzione
formula(modello.analisi.1)
Esempio 6.3.2 Con riferimento alla situazione di cui all’Esempio 6.3.1, risultati del tutto
equivalenti, ma in forma più ordinata, si ottengono ricorrendo alle seguenti istruzioni:
> x<-c(22,24,25,25,26,26,26,26,27,27,27,27,28,
28,29,30,30,30,31,32,32,32,34,34,36,36)
> y<-c(9,23,21,22,31,44,45,59,9,39,65,128,16,
28,35,44,73,78,66,89,110,122,85,118,76,84)
> (ozono.yx<-data.frame(Temperatura=x,Risposta=y))
Temperatura Risposta
1
22
9
2
24
23
3
25
21
...
...
...
24
34
118
25
36
76
26
36
84
> (formula.es1<-as.formula(paste(names(ozono.yx)[2],"~",names(ozono.yx)[1])))
Risposta ~ Temperatura
> modello.es1<-lm(formula.es1,data=ozono.yx)
> modello.es1
Call:
lm(formula = formula.es1, data = ozono.yx)
Coefficients:
(Intercept) Temperatura
-131.332
6.578
> formula(modello.es1)
Risposta ~ Temperatura
Va da sé che, alla luce di quanto sopra, avremmo potuto definire:
> formula.es1<-as.formula(paste(names(ozono.yx)[2],"~1+",names(ozono.yx)[1]))
> formula.es1
Risposta ~ 1 + Temperatura
ottenendo, coerentemente, gli stessi risultati.
166
♥
E. D. Isaia, Linguaggio R e applicazioni statistiche
6.3.2
La funzione lm(): oggetti creati in modo automatico
Come già si è detto, l’output completo della funzione lm() consiste in un oggetto
con struttura di lista, i cui elementi possono essere elencati mediante il comando
names(lm(formula=...,...)), il quale porge, appunto:
> names(lm(formula=...,...))
[1] "coefficients" "residuals"
[4] "rank"
"fitted.values"
[7] "qr"
"df.residual"
[10] "call"
"terms"
"effects"
"assign"
"xlevels"
"model"
Ciascun elemento di tale lista può essere visualizzato o acquisito per successive elaborazioni tramite il comando lm(...)$nome.elemento o, in modo del tutto equivalente,
con nome.elemento(lm(...)); ad esempio:
lm(...)$coefficients
lm(...)$fitted.values
lm(...)$residuals
↔
↔
↔
coefficients(lm(...))
fitted.values(lm(...))
residuals(lm(...))
Esempio 6.3.3 Sempre con riferimento alla situazione di cui agli Esempi 6.3.1 e 6.3.2, le
stime del modello di regressione lineare in esame nonché i valori teorici (o stimati) ŷ i , con
i = 1, 2, . . . , n, possono essere visualizzati, con un’approssimazione alla seconda cifra decimale,
mediante le istruzioni:
> coefficients(modello.es1)
(Intercept) Temperatura
-131.332357
6.578188
> round(fitted.values(modello.es1),2)
1
2
3
4
5
6
13.39 26.54 33.12 33.12 39.70 39.70
12
13
14
15
16
17
46.28 52.86 52.86 59.44 66.01 66.01
23
24
25
26
92.33 92.33 105.48 105.48
7
39.70
18
66.01
8
39.70
19
72.59
9
46.28
20
79.17
10
46.28
21
79.17
11
46.28
22
79.17
A questo punto, siamo in grado di costruire un grafico come quello proposto in figura (??.a);
a tal fine, infatti, sopperiscono le istruzioni:
> attach(ozono.yx)
> plot(Temperatura,Risposta,xlim=c(20,40),ylim=c(0,150),frame.plot = FALSE,
xlab="Temperatura (x)",ylab="Ozono (y)",pch=20,col="blue")
> lines(Temperatura,modello.es1$fitted,col="red",cex=1.5)
> detach(ozono.yx)
> grid()
167
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
oppure, in modo più diretto:
> plot(ozono.yx,xlim=c(20,40),ylim=c(0,150),frame.plot = FALSE,
xlab="Temperatura (x)",ylab="Ozono (y)",
pch=20,col="blue")
> abline(modello.es1,col="red",cex=1.5)
> grid()
ottenendo il grafico proposto in figura (??.b).
6.3.3
La funzione lm(): verifiche di ipotesi sulle stime
Come è noto, alla stima puntuale dei parametri di un modello di regressione si dovrà
affiancare la verifica di ipotesi cosı̀ come, poste
in (6.18) e (6.19). In R ciò è possibile,
2
ferma restando l’assunzione che - ∼ N 0, σ , ricorrendo all’istruzione:
> summary(lm(formula=... ,...))$coefficients
la quale porge, quale sottoforma di tabella, le stime (puntuali) dei parametri del
modello specificato, i rispettivi errori standard, i corrispondenti valori sperimentali
delle statistiche test adottate, in accordo alle (6.16) e (6.17), nonché il p − value ad
essi associato.
A tal propostio è bene tenere a mente che, nonostante l’equivalenza, asserita al
paragrafo precedente, tra le istruzioni:
> lm(formula=... ,...)$coefficients
> coefficients(lm(formula=... ,...))
l’output del comando summary(coefficients(lm(formula=... ,...))) non avrebbe alcun senso, in quanto esso porgerebbe, per le stime ottenute, la media, i quartili,
nonché il minimo ed il massimo.
Esempio 6.3.4 Con riferimento alla situazione di cui all’Esempio 6.3.1, abbiamo:
> summary(modello.es1)$coefficients
Estimate Std. Error
t value
Pr(>|t|)
(Intercept) -131.332357 42.474389 -3.092036 0.0049817779
Temperatura
6.578188
1.460964 4.502636 0.0001471189
Dal momento che i p − value ottenuti sono prossimi allo zero, siamo portati a rifiutare le
ipotesi nulle H0 : α = 0 e H0 : β = 0.
Si noti come il risultato dell’istruzione:
> summary(coefficients(modello.es1))
Min. 1st Qu.
Median
Mean 3rd Qu.
-131.300 -96.850 -62.380 -62.380 -27.900
168
Max.
6.578
E. D. Isaia, Linguaggio R e applicazioni statistiche
verrebbe ad essere del tutto privo di senso.
♥
Desiderando visualizzare anche il valore sperimentale della statistica test (6.21) ed
il corrispondente p − value, onde avere un’idea circa la bontà di adattamento del
modello di regressione specificato, conviene ricorrere all’istruzione:
> summary(lm(formula=... ,...))
la quale porge:
— alcune statistiche riassuntive circa i residui della regressione;
— la tabella riguardante la verifica delle ipotesi (6.18) e (6.19) concernenti le stime
dei parametri del modello;
— l’errore standard dei residui s, in accordo alla (6.15), con i rispettivi gradi di
libertà;
— il valore del quadrato del coefficiente di correlazione lineare r, nonché il corrispondente valore “corretto” (cfr. Osservazione 6.4.1);
— il valore sperimentale della statistica (6.21), con i relativi gradi di libertà a
numeratore e denominatore, nonché il p − value corrispondente.
Esempio 6.3.5 Sempre con riferimento alla situazione di cui all’Esempio 6.3.1, da quanto
sopra, abbiamo:
> summary(modello.es1)
Call:
lm(formula = formula.es1, data = ozono.yx)
Residuals:
Min
1Q Median
-37.28 -19.14 -5.49
3Q
11.45
Max
81.72
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -131.332
42.474 -3.092 0.004982 **
Temperatura
6.578
1.461
4.503 0.000147 ***
--Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05
‘.’
0.1
‘ ’
Residual standard error: 26.99 on 24 degrees of freedom
Multiple R-Squared: 0.4579,Adjusted R-squared: 0.4353
F-statistic: 20.27 on 1 and 24 degrees of freedom,p-value: 0.0001471
169
1
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Nonostante un basso valore sperimentale del coefficiente di correlazione lineare (r = 0.2097),
il p − value prossimo a zero associato al valore sperimentale della statistica test (6.21) ci
consente di affermare che i dati campionari ben si adeguano al modello di regressione lineare
proposto.
♥
Qui nel seguito riportiamo i comandi permettono di estrarre in modo diretto alcuni
elementi dell’output generato da summary(lm(formula=...,...)):
— summary(lm(formula=...,...))$sigma: l’errore standard s;
— df.residual(lm(formula=...,...)): i gradi di libertà impiegati per il calcolo
di s2 ;
— deviance(lm(formula=...,...)): la devianza tra valori effettivi e teorici, cioè
il numeratore di s2 ;
— summary(lm(formula=...,...))$r.squared: la “frazione della varianza spiegata dalla retta di regressione” ovvero il quadrato del coefficiente di correlazione;
— summary(lm(formula=...,...))$fstatistic: il valore sperimentale della statistica F con i corrispondenti gradi di libertà.
Esempio 6.3.6 Con riferimento all’analisi di cui all’Esempio 6.3.5 ed alla luce di quanto
sopra, si considerimo le istruzioni:
> summary(modello.es1)$sigma
[1] 26.99364
> df.residual(modello.es1)
[1] 24
> deviance(modello.es1)
[1] 17487.76
> (summary(modello.es1)$sigma)^2*df.residual(modello.es1)
[1] 17487.76
> summary(modello.es1)$r.squared
[1] 0.4579178
> summary(modello.es1)$fstatistic
value
numdf
dendf
20.27373 1.00000 24.00000
L’output di summary(modello.es1)$fstatistic è un vettore numerico di tre elementi, il
primo dei quali, il valore di F sperimentale, può essere acquisito, ad esempio, con l’istruzione
> summary(modello.es1)$fstatistic[1]
value
20.27373
170
E. D. Isaia, Linguaggio R e applicazioni statistiche
Si osservi, infine, che l’output dell’istruzione summary(modello.es1)$coefficients è rappresentato da una matrice di ordine 2 × 4 e quindi desiderando estrarre, ad esempio, l’errore
standard associato alla stima del coefficiente β, sarà sufficiente l’istruzione:
> summary(modello.es1)$coefficients[2,3]
[1] 4.502636
♥
Osservazione 6.3.1 La funzione summary(...) sin qui impiegata è assai generica;
nel caso dell’analisi della regressione si dovrebbe, a rigore di logica, ricorre alla funzione specifica summary.lm(...), nonostante i risultati siano del tutto equivalenti.
Il lettore, tuttavia, può ottenere utili informazioni consultando l’aiuto in linea di
summary.lm.
6.3.4
La funzione predict.lm(): intervalli di confidenza e di previsione
Una volta stimata la retta di regressione e verificatane la bontà di adattamento,
può essere di interesse determinare, perlomeno in corrispondenza ad alcuni valori di
interesse del predittore, gli itervalli di condifenza e/o gli intervalli di previsione per la
variabile risposta, cosı̀ come indicato al paragrafo 6.2.3.
A tal fine, nonostante sia sempre possibile redarre una funzione ad hoc basata sulle
(6.24) e (6.23), vediamo come sfruttare la particolare funzione predict.lm(...), la
cui sintassi minima è:
predict.lm(object,data,interval=...,level=...)
dove:
— object: è l’oggetto, di classe lm, che definisce il modello di regressione in esame;
— data: è il data frame contenente le osservazioni campionarie di interesse (valori
osservati e/o valori “futuri” del predittore);
— interval=: indica se trattasi di un intervallo di confidenza (confidence) ovvero
di previsione (prediction);
— level=: specifica il consueto livello di significatività 1 − α da utilizzare. Per
default, level=0.95.
L’output della funzione è una matrice di dimensione n × 3 contenente, in corrispondenza a ciascuno degli n valori del data frame specificato in data, la stima ŷ (fit), il
limite inferiore (lwr) e quello superiore (upr) dell’intervallo di interesse.
171
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
A tal proposito, desiderando ottenere un intervallo di confidenza e/o di previsione per
uno o più particolari valori del predittore, siano essi interni e/o esterni al range dei
valori osservati, si dovrà creare un nuovo data fame ad hoc, contenente, appunto, tali
valori.
Esempio 6.3.7 Sempre con riferimento alla situazione di cui all’Esempio 6.3.1, gli intervalli
di confidenza e di previsione, al livello di condifenza del 95%, in corrispondenza a ciascuna
delle n = 26 osservazioni campionarie, si ottengono facilmente con le istruzioni:
> predict.lm(modello.es1,ozono.yx,interval="confidence",level=0.95)
fit
lwr
upr
1
13.38779 -9.968481 36.74406
2
26.54416 8.298502 44.78983
3
33.12235 17.188915 49.05579
...
...
...
...
24 92.32605 73.329223 111.32287
25 105.48242 81.302257 129.66259
26 105.48242 81.302257 129.66259
> predict.lm(modello.es1,ozono.yx,interval="prediction",level=0.95)
fit
lwr
upr
1
13.38779 -47.022124 73.79770
2
26.54416 -32.079605 85.16793
3
33.12235 -24.823454 91.06816
...
...
...
...
24 92.32605 33.464163 151.18793
25 105.48242 44.749216 166.21563
26 105.48242 44.749216 166.21563
Desideando, ora, costruire un intervallo di previsione, al livello di condifenza del 90%, per la
concentrazione di ozono in corrispondenza ad una temperatura ambientale di 23 e 38 gradi
Celsius, possiamo impartire le istruzioni:
> ozono.yx.new<-data.frame(Temperatura=c(23,38))
> predict.lm(modello.es1,ozono.yx.new,interval="prediction",level=0.90)
fit
lwr
upr
1 19.96598 -29.3131 69.24505
2 118.63880 66.3090 170.96861
Si osservi che le istruzioni:
>
>
>
>
new<-data.frame(Temperatura=c(20:40))
IC.modello.es1<-predict(modello.es1,new,interval="confidence",level=.95)
IP.modello.es1<-predict(modello.es1,new,interval="prediction",level=.95)
matplot(new$Temperatura,cbind(IC.modello.es1,IP.modello.es1[,-1]),
xlim=c(20,40),ylim=c(0,150),frame.plot=FALSE,type="l",
lty=c(1,2,2,5,5),col=c("blue","red","red","black","black"),
172
E. D. Isaia, Linguaggio R e applicazioni statistiche
ylab="Concentrazione di ozono",xlab="Temperatura ambientale")
> testo<-c("Stime","Retta di regressione","I.C. (95%)","I.P. (95%)")
> legend(20,148,lty=c(0,1,2,5),merge=TRUE,pch=c("+",-1,-1,-1),
legend=testo,col=c("green","blue","red","black"),cex=.85,bty="n")
> grid()
> points(ozono.yx$Temperatura,drop(modello.es1$fitted),type="p",pch="+",
cex=2,col="green")
consentono di ottenere la figura (??) che riporta il grafico della nuvola di punti di coordinate
(xi , yi ), della stima della retta di regressione, nonché i rami di iperbole corrispondenti ai limiti
inferiore e superiore degli intervalli di confidenza e di previsione testè ottenuti.
♥
6.3.5
Per un’analisi dei residui
Alla stima ed alla verifica delle ipotesi statistiche concernenti i parametri di un modello
di regressione è buona norma, per i motivi di cui già si è detto, far seguire un’analisi
empirica dei residui,
In R ciò è possibile semplicemente ricorrendo alla funzione plot(lm(formula=...)),
la quale porge, in modo del tutto automatico, i grafici di cui si disse al paragrafo
6.2.4.
Esempio 6.3.8 Sempre riprendendo i dati di cui all’Esempio 6.3.1, le istruzioni:
> par(mfrow=c(2,2))
> plot(modello.es1,col="blue")
> par(mfrow=c(1,1))
producono i grafici riportati in figura (??). *** eventuale commento ***
Val qui la pena vedere in dettaglio le possibili istruzioni che consentono di ottenere
i residui standardizzati nonché le “distanze di Cook”. Dal momento che entrambe
dipendono in modo esplicito dalle quantià h i , che come si è visto concorrono alla stima
della varianza dei residui σ 2 , vediamo dapprima come calcolare tali grandezze.
Posto che gli oggetti xi e yi contengano le n osservazioni campionarie (x i , yi ), definito
il modello di regressione lineare modello<-lm(yi~xi), ricordando la (6.14), abbiamo:
> hi<-(sum(xi^2)-2*xi*sum(xi)+n*xi^2)/(n*sum(xi^2)-(sum(xi))^2)
da cui, introdotti gli oggetti:
> residui<-modello$residuals
> summary.lm(modello)$sigma
essendo i residui standardizzati
s
yi − ŷi , si ha:
>
1 − hi
173
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> residui.std<-residui/(s*sqrt(1-hi))
ed infine, ricordando la (6.25):
distanze.cook<-(residui/(s*(1-hi)))^2*(hi/2)
Tuttavia R prevede una particolari funzioni che consentono il calcolo diretto di tali
grandezze, più precisamente trattasi delle funzioni:
— lm.influence(lm(formula=...,...)): essa fornisce, sottoforma di lista, i
seguenti oggetti:
– hat: i valori hi in corrispondenza a ciascuna realizzazione x i di X;
– coefficients: le differenze8 a − a−i , b − b−i , ovvero le differenze tra le
stime di α e di β e quelle che si otterrebbero qualora si escludesse la i-esima
osservazione campionaria, e ciò ∀ i = 1, 2, . . . , n;
– sigma: le stime s2−i di σ 2 qualora si escludesse la i-esima osservazione
campionaria, e ciò ∀ i = 1, 2, . . . , n;
I valori contenuti in coefficients e sigma possono essere utilizzati per individuare quali sono le realizzazioni x i di X che hanno un peso determinante nel
processo di stima del modello di regressione.
— rstandard(lm(formula=...,...)): fornisce i residui standardizzati;
— cook.distance(lm(formula=...,...)): porge le “distanze di Cook”.
Esempio 6.3.9 Sempre riprendendo i dati di cui all’Esempio 6.3.1, le istruzioni: *** DA
FARE ***
> ***
*** eventuale commento ***
Ricordiamo, infine, la possibilità di ricorrere alle seguenti due funzioni:
— rstudent(lm(formula=...,...)): fornisce i residui “studentizzati”, cioè i residui standardizzati ricorrendo alla stima s 2−i di σ 2 ;
8
Acquisibili ricorrendo alle istruzioni lm.influence(lm(formula=...,...))$coefficients[,1] e
lm.influence(lm(formula=...,...))$coefficients[,2].
174
E. D. Isaia, Linguaggio R e applicazioni statistiche
— influence.measures(lm(formula=...,...)): porge, sottoforma di tabella ed
in corrispondenza a ciascuna determinazione x i di X, alcune misure riassuntive
di diagnosi dei residui9 con indicazione, mediante asterisco, dei valori campionari
“sospetti”.
Esempio 6.3.10 Sempre riprendendo i dati di cui all’Esempio 6.3.1, le istruzioni: *** DA
FARE ***
> influence.measures(modello.es1)
*** eventuale commento ***
6.4
4
Sulla regressione multipla: il modello y, X β, σ 2 In
6
Cappellino
Si immagini che le misurazioni, effettuate su n individui, di p+1 variabili quantitative
siano rappresentabili mediante i vettori di y, x 1 , x2 , . . . , xp ∈ IRn, ed altresı̀ si supponga di volere “spiegare” la variabile y mediante i p predittori (o variabili esplicative)
xj . Abitualmente tali predittori vengono supposti essere linearmente indipendenti, il
che non implica che essi lo siano anche sotto il profilo statistico 10 .
Si immagini che i vettori x1 , x2 , . . . , xp , y ∈ IRn costituiscano un campione casuale di
dimensione n di altrettante realizzazioni di p + 1 v.c. X 1 , X2 , . . . , Xp , Y .
Per cose note, la migliore approssimazione di Y mediante una funzione delle p v.c.
Xj , abitualmente dette predittori o variabili esplicative, corrisponde al valor medio
condizionato IE[Y |X1 , X2 , . . . , Xp ]. Se introduciamo, ora, l’ipotesi:
IE[Y |X1 , X2 , . . . , Xp ] = β0 +
p
!
β0 Xj
(6.26)
j=0
perveniamo al modello di regressione lineare multipla:
Y = β0 +
p
!
β0 Xj + -
j=0
dove - è una v.c. non correlata con le v.c. X j , con valor medio nullo e varianza σ 2 .
Per le ipotesi fatte, tra le realizzazioni campionarie x i1 , xi2 , . . . , xip , -i , yi delle v.c.
X1 , X2 , . . . , Xp , -, Y sussiste, per j = 1, 2, . . . , p e i = 1, 2, . . . , n, la relazione:
yi = β0 +
p
!
β0 Xij + -i
j=0
9
10
Tra esse i valori di hi e di di .
Inserire in nota un esempio semplice e breve.
175
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
che può essere posta nella forma compatta:
y = Xβ + %
(6.27)
dove y = [y1 , y2 , . . . , yn ]t è il vettore delle n realizzazioni campionarie indipendenti y i
di Y , β = [β0 , β1 , . . . , βp ]t rappresenta il vettore dei parametri incogniti del modello,
% = [-1 , -2 , . . . , -n ]t è il vettore degli errori -i mentre:

1
 1

X=
. . .
1
x11
x21
...
xn1
x12
x22
...
xn2
...
...
...
...

x1p
x2p 


... 
xnp
(6.28)
è una matrice di ordine n × (p + 1) la cui prima colonna contiene i coefficienti della
costante del modello e le colonne successive le realizzazioni campionarie indipendenti
delle p v.c. Xj .
Seguento la letteratura, indichiamo
il modello di
regressione lineare multipla corri,
2
spondente alla (6.27) con la tripla y, X β, σ In , dove chiaramente In è una matrice
identità di dimensione n × n.
6.4.1
Stima e verifica di ipotesi sui parametri del modello
Il problema che ci si pone è la stima dei parametri β O , β1 , . . . , βp del modello nonché
della varianza del termine di disturbo -.
Il ricorso al metodo dei minimi quadrati comporta la minimizzazione, rispetto ai p + 1
parametri del modello, della funzione:
F (β0 , β1 , . . . , βp ) =
n
!
i=1
(yi − β0 −
p
!
βj xij )2
j=1
Ora, come facilmente si può verificare, i coefficienti del sistema delle equazioni normali
corrispondono al prodotto matriciale X t X, infatti:

X X=
t
(n
n
i=1 xi1
(
(n
 n
2
 i=1 xi1
i=1 xi1
(
(
n
 n x
 i=1 i2
i=1 xi1 xi2


..

( .
n
i=1
xip
(n
(n
i=1
i=1
(n
xi2
...
xi1 xi2 . . .
i=1
x2i2
...
..
..
.
.
...
(n
(n
i=1 xi1 xip
i=1 xi2 xip . . .
176
(n
(n
i=1
i=1
(n
xip


xi1 xip 


xi2 xip 



..

.

(n
2
i=1 xip
i=1
E. D. Isaia, Linguaggio R e applicazioni statistiche
mentre i termini noti del sistema delle equazioni normali corrispondono al vettore
X y, infatti:

 (
n
yi
i=1

(

 n
 i=1 xi1 yi 

(

 n
X y =  i=1 xi2 yi 




..


.

(
n
i=1
xip yi
Pertanto la condizione dei minimi quadrati porge, quale stima di β, il vettore:
4
6−1
b = Xt X
(6.29)
Xt y
Ciò premesso, è immediato dimostare che lo stimatore b,ottenuto in accordo al metodo
dei minimi quadrati, è uno stimatore corretto di β.
Infatti, dal momento che X è una costante ed osservando che IE[y] = X β, si ha:
IE[b] = IE[(Xt X)−1 Xt y] = (Xt X)−1 Xt X β = β
Con un ragionamento simile, otteniamo la varianza dello stimatore b; ricordando che
V ar[y] = V ar[%] = σ 2 In , sarà:
V ar[b] = V ar[(Xt X)−1 Xt y] = (Xt X)−1 (Xt X)−1 Xt V ar[y] X =
= σ 2 (Xt X)−1 (Xt X)−1 Xt In X = σ 2 (Xt X)−1
(6.30)
mentre una stima corretta della varianza σ 2 è offerta dallo stimatore:
S2 =
||y − ŷ||2
||y − X b||2
=
n−p−1
n−p−1
(6.31)
È qui appena il caso di osservare che tra tutti gli stimatori corretti di β, b è quello
a varianza minima; tale proprietà nonché quella circa la correttezza dello stimatore
posto in (6.31) discendono dal teorema di Gauss-Markov generalizzato.
Per approfondimenti a tal riguardo, si rimanda ai testi di McCullagh, Nelder (2000)
e Saporta (1990).
Se introdiciamo, ora, l’ipotesi che ∀ i = 1, 2, . . . , n - i ∼ N (0, 1), y può allora essere
inteso quale vettore gaussiano multidimensionale, cioè:
4
6
y ∼ Nn X β, σ 2 In )
177
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
con densità di probabilità, quindi:
L(y, β, σ ) =
2
=
:
1
(y − X β)t (y − X β)
√
exp
−
2 σ2
σ n ( 2 π)n
:
<
1
y yt − 2 β t Xt y − β t Xt X β
√
exp
−
2 σ2
σ n ( 2 π)n
<
Sotto tale ipotesi, la stima di massimaverosomiglianza per β viene a coincidere con la
stima proposta in (6.29) e ottenuta con il metodo dei minimi quadrati; in più, essendo
b una trasformata lineare di un vettore gaussiano, si ha:
4
b ∼ Np+1 β, σ 2 (Xt X)−1
6
(6.32)
Quanto alla varianza σ 2 , il metodo della massimaverosomiglianza porge la stima
n−1 ||y−X b||2 , la quale dovrà, quindi, essere corretta, in accordo alla (6.31), mediante
il fattore n − n
p − 1 . A tal proposito, si dimostra, poi, che:
||y − X b||2
(n − p − 1) S 2
=
∼ χ2n−p−1
σ2
σ2
(6.33)
Focalizzando l’attenzione sul j-esimo coefficiente di regressione empirico b j , in virtù
della (6.30) sarà:
V ar[bj ] = σb2j = σ 2 (Xt X)−1
jj
(6.34)
dove (Xt X)jj indica l’elemento jj-esimo di (Xt X)−1 e, ricordando la (6.31), la stima
corretta di σb2j è offerta da:
s2bj =
||y − X b||2
(Xt X)−1
jj
n−p−1
Ne segue11 , che la variabile test:
Tbj =
bj − βj
bj − βj
=N
sbj
||y − X b||2
(Xt X)−1
jj
n−p−1
viene a possedere ditribuzione t di Student con n − p − 1 gradi di libertà.
11
Si noti che, per le ipotesi fatte, bj ∼ N (βj , σb2j ).
178
(6.35)
E. D. Isaia, Linguaggio R e applicazioni statistiche
Tali considerazioni consentono di pervenire alla costruzionione di intervalli di confidenza, ad un prefissato livello 1 − α, per i p + 1 parametri incogniti β 0 , β1 , . . . , βp o
di sottoporre a verifica le seguenti ipotesi statistiche, ∀ j = 0, 1, 2, . . . , p:
+
H0 : βj = 0
H1 : βj 3= 0
(6.36)
con l’avvertenza che le statistiche test coinvolte non risultano tra loro indipendenti,
non essendolo i coefficienti bj tra loro.
6.4.2
Sul coefficiente di correlazione multipla
Com’è noto, il coefficiente di correlazione multipla tra Y e le p+1 variabili esplicative 12
può essere calcolato direttamente in base alla matrice X dei coefficienti del modello
di regressione lineare; infatti, indicando con X ∗ la matrice “centrata” di X13 e con
y∗ il vettore “centrato” di y 14 , risulta:
t
R2 =
t
t
y∗ X∗ (X∗ X∗ )−1 X∗ y∗
(6.37)
t
y∗ y∗
Ora, un semplice calcolo consente di porre la (6.37) nella forma:
R2 =
||y − ȳ||2 − ||y − X b||2
||y − ȳ||2
il che indica che il quadrato del coefficiente di regressione multipla può essere inteso
quale rapporto tra la varianza spiegata dal modello di regressione e la varianza totale
di Y . Tale considerazione (cfr. Osservazione 6.4.1) ci permette effettuare un test
circa la bontà di adattamento del modello di regressione sulla base di un’opportuna
trasformata di R2 .
Infatti, dal momento che:
||y − ȳ||2 = ||y − X b||2 + ||X b − ȳ||2
e tenendo presente l’ipotesi intordotta sulle - i , si ha:
— ∀ β:
||y − X b||2
∼ χ2n−p−1
σ2
12
Includendo la costante.
¯ j , con
Ossia la matrice
di dimensione n × p + 1 le cui colonne contengono gli scarti xij − x̄
( di(
p
¯j = n
ovviamente x̄
x .
i=1
j=1 ij
14
Leggasi il vettore degli scarti yi − ȳ.
13
179
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
— vera l’ipotesi βj = 0, con j = 1, 2, . . . , p e β0 qualsiasi:
||X b − ȳ||2
∼ χ2p
σ2
— vera l’ipotesi βj = 0, con j = 1, 2, . . . , p e β0 qualsiasi:
||y − ȳ||2
∼ χ2n−1
σ2
La bontà di adattamento del modello di regressione multipla può essere misurata
ricorrendo al rapporto tra la varianza spiegata dal modello di regressione e la varianza
||X b − ȳ||2
R2 .
residua, in simboli
2 =
||y − X b||
1 − R2
Ora, sotto l’ipotesi βj = 0, con j = 1, 2, . . . , p e β0 qualsiasi, risulta:
R2 n − p − 1
∼ Fp;n−p−1
p
1 − R2
dove, come di consueto, Fp;n−p−1 indica la ditribuzione F di Snedecor con, rispettivamente, p gradi di libertà a numeratore e n − p − 1 gradi di libertà a denominatore.
Si tenga presente che la lettura del solo valore empirico del coefficiente di correlazione
multipla potrebbe trarre in inganno; infatti si potrebbe osservare un R 2 prossimo
all’unità e al contempo accettare “in blocco” le ipotesi H 0 : bj = 0. Tale è certamente
il caso se i predittori sono fortemente correlati tra loro (cfr. paragrafo 6.4.4).
Osservazione 6.4.1 L’accettazione, ∀j = 1, 2, . . . , p, delle ipotesi di nullità dei coefficienti di regressione (H0 : βj = 0, con β0 qualunque) equivale pertanto all’accettazione che il coefficiente di correlazione multiplo (teorico) ρ sia nullo, cioè dell’ipotesi
di non-regressione. Se tale è il caso, allora ρ viene a possedere distribuzione Beta di
parametri p/2 e (n − p − 1)/2, per cui:
IE[R2 ] =
p
n−1
V ar[R2 ] =
2 p (n − p − 1
(n2 − 1) (n − 1)
Viceversa se l’ipotesi di non-regressione è rifiutata (ρ 3= 0), allora la distribuzione di
R2 assume una forma più complessa ed R 2 viene ad essere uno stimatore distorto. A
p (1 − ρ) + O(n−1 ). Per tali motivi
tal propostito si dimostra che IE[R 2 ] = ρ2 + n −
1
a volte si ricorre ad un valore di R 2 “corretto” (adjusted R squared):
∗
R2 =
(n − 1) R2 − p
n−p−1
che presenta, però, lo svantaggio di condurre a valori negativi (!) se il coefficiente di
correlazione multipla è prossimo allo zero.
180
E. D. Isaia, Linguaggio R e applicazioni statistiche
6.4.3
Sulla previsione e l’analisi dei residui
Dal momento che su tali argomenti valgono, in generale, le considerazioni fatte in
occasione dell’analisi della regressione lineare semplice, nel seguito ci limitiamo a
presentare alcuni risultati di interesse, rimandando per dettagli ai paragrafi 6.2.3 e
6.2.4.
— intervallo di previsione: posto x0 = [1, x10 , x20 , . . . , xp0 ]t il vettore contenente i
valori di interesse dei predittori i corrispondenza ai quali si desidera “prevedere”
il valore di y, la v.c. ŷ0 = xt0 b, sotto le ipotesi fatte circa le -i , ha distribuzione
normale di parametri xt0 β0 e σ 2 xt0 (Xt X)−1 x0 .
Posto y0 = IE[y|X1 = x10 ∩ . . . ∩ Xp = xp0 ] la v.c. standardizzata y0 − ŷ0 ,
utilizzando lo stimatore corretto posto in (6.31):
S
/
y0 − ŷ0
1 + xt0 (Xt X)−1 x0
viene a possedere distribuzione t di Student con n − p − 1 gradi di libertà., da
cui l’intervallo di previsione per y0 :
ŷ0 ± n−p−1 t1−α/2 s
/
1 + xt0 (Xt X)−1 x0
— i residui standardizzati: prendendo le mosse dall’uguaglianza y = y − X b+ X b
e ricordando che (y − X b) ⊥ X b, si ha:
V ar[y] = V ar[y − X b] + V ar[X b]
da cui:
V ar[y − X b] = σ 2 [In − X (Xt X)−1 Xt ]
Indicando con hi il generico i-esimo termine della diagonale di X (X t X)−1 Xt ,
(
con n−1 ≤ hi ≤ 1 e ni=1 hi = n − p − 1, abbiamo σy2i −ŷi = σ 2 (1 − hi ), donde,
sostituendo a σ 2 la sua stima corretta, la stima della varianza dei residui:
s2yi −ŷi = s2 (1 − hi )
181
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
6.4.4
Sulla multicollinearità
La principale fonte di instabilità della stima di β è rappresentata dall’ordine di grandezza delle varianze σb2j ; tenendo a mente la (6.34), è facile intuire che qualora il
determinante di Xt X fosse prossimo a zero, gli elementi di (X t X)−1 tenderebbero
ad assumere valori elevati e di conseguenza le σ b2j , sı̀ che i parametri del modello
verrebbero ad essere stimati in modo impreciso.
Tra le svariate cause che producono tale anomalia, una è certamente la la correlazione tra le variabili esplicative; tale situazione viene indicata con il termine di
multicollinearità.
Desiderando, in qualche modo, verificare tale affermazione, posto, per semplicità,
∗ X una matrice “standardizzata”15 di dimensione n × p ed indicando con con R la
matrice di correlazione tra i p predittori, è facile verificare la relazione n R = ∗ Xt ∗ X.
Ciò premesso, si ha V ar[b] = σ 2 n−1 R−1 e, pertanto, con riferimento al suo j-esimo
elemento, la corrispondente stima corretta può essere posta nella forma:
s2bj =
σ2
(R−1 )jj
n
(6.38)
dove, chiaramente, (R−1 )jj indica il j-esimo termine della diagonale di R −1 .
Per inciso, si osservi che (R−1 )jj = (1 − Rj2 )−1 , dove Rj2 corrisponde al quadrato del
coefficiente di correlazione multipla tra j-esimo predittore e le restanti p − 1 variabili
esplicative. Evidentemente, qualora i predittori fossero tra loro ortogonali si avrebbe,
∀ j = 1, 2, . . . , p, Rj2 = 0 e di conseguenza s2bj = σ 2 n−1 . In particolare, poi, i termini
(1 − Rj2 )−1 vengono abitulamente detti fattori di inflazione della varianza (VIF), e la
loro media può essere considerata quale indice globale di multicollinearità.
Il problema della multicollinearità tra i predittori può essere risolto, o perlomeno
attenuato, ricorrendo a diverse strategie 16 proposte in letteratura, quali ad esempio,
la regressione per componenti principali, la ridge regression, o le tecniche di selezione,
quali la backward regression, la forward regression o, ancora, la stepwise regression.
Gli algoritmi più diffusi, e implementati sulla maggior parte dei pacchetti statistici in
commercio, sono senza dubbio quelli basati sulle tecniche di selezione, anche se queste
non sono esenti da critiche, ad esempio mal si prestano là dove si richiede la stima di
un modello di previsione.
Sostanzialmente tali tecniche tendono a ridurre un problema di regressione multipla
a p variabili esplicative ad un analogo a q < p predittori, questi ultimi scelti tra quelli
che apportano il maggior contributo ad R 2 . In particolare:
15
In altri termini, si suppone, cioè che tutte le variabili del modello di regressione multipla siano
standardizzate. Ovviamente, sotto tali ipotesi, si ha b = (Xt X)−1 = (∗ Xt ∗ X)−1 .
16
Presupponendo una certa discrezionalità, da parte del ricercatore, sul numero dei predittori che
concorrono a spiegare y.
182
E. D. Isaia, Linguaggio R e applicazioni statistiche
— con la backward regression si inizia con la stima del modello completo a p
predittori e si elimina la variabile esplicativa che ha la minore influenza su R 2 ,
o equivalentemente quella che presenta il maggior p − value associato al test
su βj . Quindi si effettua una nuova stima del modello a p − 1 predittori e cosı̀
via sino all’eliminazione di p − 1 variabili esplicative o al raggiungimento di una
condizione di arresto.
— con la forward regression si inizia con la stima del modello ad una sola variabile
esplicativa, quella che ha maggior influenza su R 2 , e via, via, secondo lo stesso
criterio, si aggiungono i restanti predittori. Il processo iterativo ha termine non
appena R2 raggiunge una soglia prefissata.
— la stepwise regression può essere intesa come un perfezionamento dell’algoritmo
della forward regression, nel senso che ad ogni passo viene effettuato un test
(su βj o su R2 ) teso a non introdurre un predittore non significativo oppure ad
eliminare le eventuali variabili esplicative non più significative una volta inserita
nel modello l’ultima variabile selezionata. Abitualmente il processo ha termine
non appena R2 raggiunge una soglia prefissata.
6.5
La regressione multipla in R
Nel caso si debba affrontare un’analisi di regressione lineare multipla in R si ricorre
alla funzione lm() già affrontata in dettaglio e per la quale, in linea generale, valgono
le considerazioni fatte ai paragrafi 6.3 e successivi.
Nel seguito, pertanto, focalizzeremo la nostra attenzione alla risoluzione di problemi
più specifici, quali ... ***
6.5.1
Definizione del modello e l’istruzione model.matrix(lm(...))
Come già si disse, in R è buona norma organizzare le ossevazioni campionarie in
un data frame, introdurre in modo esplicito il modello
di regressione
lineare mediante
,
2
un’opportuna formula, che nel caso del modello y, X β, σ In a p predittori potrebbe
presentarsi:
> formula<-as.formula(Risposta~var1+var2+ ... +varp)
o, in modeo del tutto equivalente:
> formula<-as.formula(Risposta~.)
e successivamente definire l’oggetto di classe lm che conterrà i risultati di interesse
nonché altre informazioni necessarie per uleriori elaborazioni; ad esempio mediante
l’istruzione:
183
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
> modello<-lm(formula,data=data frame)
Un differente modo di procedere consiste nel definire la formula a partire dal vettore
delle n osservazioni campionarie di Y e dalla matrice delle realizzazioni campionarie
dei p predittori Xj , oggetti che potrebbero coincidere con gli elementi del data frame;
seguendo tale approccio, potrebbero valere le istruzioni:
> formula<-as.formula(y~Xp)
> modello<-lm(formula)
dove, è bene tenerlo a mente, Xp è una matrice di ordine n × p.
Esempio 6.5.1 A puro scopo didattico, si immagini che per un modello di regressione lineare
multipla a due sole variabili esplicative si siano ottenute le seguenti osservazioni campionarie:
xi1
xi2
yi
8.04
7.46
10.2
6.95
6.77
8.5
7.58
12.74
13.1
8.81
7.11
9.0
8.33
7.81
11.5
9.96
8.84
14.9
7.24
6.08
6.5
4.26
5.39
4.0
10.84
8.15
12.2
4.82
6.42
7.0
5.68
5.73
5.5
Scelto di raccogliere tali informazioni nel data frame dati composto dai tre oggetti x1, x2 e
Risposta:
> dati<-data.frame(
x1=c(8.04,6.95,7.58,8.81,8.33,9.96,7.24,4.26,10.84,4.82,5.68),
x2=c(7.46,6.77,12.74,7.11,7.81,8.84,6.08,5.39,8.15,6.42,5.73),
Risposta=c(10.2,8.5,13.1,9.0,11.5,14.9,6.5,4.0,12.2,7.0,5.5))
possiamo definire la formula per il modello di regressione Y = β0 + β1 X1 + β2 X2 + * e,
successivamente, l’oggetto modello.1 di classe lm tramite le consuete istruzioni:
> formula.1<-as.formula(Risposta~.)
> modello.1<-lm(formula,data=dati)
Alternativamente, ferma restando la sruttura del data frame dati, introdotta la matrice Xp
delle n realizzazioni campionarie yi1 e xi2 :
> attach(dati)
> Xp<-as.matrix(cbind(x1,x2))
> detach(dati)
possiamo definire la formula e successivamente l’oggetto modello.2 di classe lm come:
> formula.2<-as.formula(Risposta~Xp)
> modello.2<-lm(formula.2,data=dati)
184
E. D. Isaia, Linguaggio R e applicazioni statistiche
Naturalmente, i due oggetti modello.1 e modello.2 sono equivalenti e si riferiscono al
medesimo modello di regressione.
♥
Ora, perlomeno in alcune
situazioni, potrebbe
tornare utile operare direttamente sulla
,
2
matrice X del modello y, X β, σ In . Naturalmente, questa potrebbe essere definita
in modo esplicito, ricorrendo ad esempio all’struzione:
> X<-cbind(c(rep(1,length(var1))),var1+var2+ ... +varp)
dove c(rep(1,length(var1))) crea un vettore colonna di n =length(var1) elementi unitari. Tuttavia in R possiamo automatizzare tale processo ricorrendo alla
semplice istruzione:
> X<-model.matrix(modello)
Esempio 6.5.2 Come si disse, gli oggetti modello.1 e modello.2,
definiti all’Esempio 6.5.1,
(2
si riferiscono entrambi al modello di regressione Y = β0 + j=1 βj Xj + *; entrambi, quindi,
saranno dotati della stessa matrice X, la cui trasposta (X t ) risulta infatti:
> t(model.matrix(modello.1))
1
2
3
4
(Intercept) 1.00 1.00 1.00 1.00
x1
8.04 6.95 7.58 8.81
x2
7.46 6.77 12.74 7.11
attr(,"assign")
[1] 0 1 2
> t(model.matrix(modello.2))
1
2
3
4
(Intercept) 1.00 1.00 1.00 1.00
Xpx1
8.04 6.95 7.58 8.81
Xpx2
7.46 6.77 12.74 7.11
attr(,"assign")
[1] 0 1 1
5
6
7
8
9
10
11
1.00 1.00 1.00 1.00 1.00 1.00 1.00
8.33 9.96 7.24 4.26 10.84 4.82 5.68
7.81 8.84 6.08 5.39 8.15 6.42 5.73
5
6
7
8
9
10
11
1.00 1.00 1.00 1.00 1.00 1.00 1.00
8.33 9.96 7.24 4.26 10.84 4.82 5.68
7.81 8.84 6.08 5.39 8.15 6.42 5.73
Nonostante l’aspetto, l’output di model.matrix(...) è, a tutti gli effetti una matrice, infatti:
> is.matrix(model.matrix(modello.1))
[1] TRUE
e di conseguenza può essere utilizzato per successive elaborazioni.
♥
Palesemente, le considerazioni sin’ora fatte si applicano, mutatis mutandi, ad un
modello di regressione lineare semplice, per cui evidentemente risulta p = 1.
185
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Esempio 6.5.3 Con riferimento alla situazione di cui all’Esempio 6.3.1, definita la matrice
X come X<-model.matrix(modello.es1), il vettore delle stime dei parametri β 0 e β1 del
modello di regressione semplice Y = β0 + β1 X1 + * può essere calcolato in modo diretto come:
> solve(t(X)%*%X)%*%t(X)%*%y
[,1]
[1,] -131.332357
[2,]
6.578188
risultato ovviamente coincidente con l’ouput di modello.es1.
6.5.2
♥
Ridefinizione del modello: l’istruzione update(lm(...))
A volte, per svariati motivi, nel corso di una sessione di lavoro può accadere di dovere
ridefinire un modello di regressione: aggiungere o eliminare alcuni predittori, sopprimere la costante, ... Anziché ridefinire il modello ex-novo, R prevede la funzione
update(lm(...)), la cui sintassi autoesplicativa è:
update(lm(<old>),lm(<new>))
Posto di avere precedentemente definito l’oggetto modello<-lm(y~x1), si immagini
di volere vedere l’effetto sul coefficiente di correlazione multipla R dell’inserimento di
un secondo predittore x2; ciò può avvenire ricorrendo alla semplice istruzione:
> sqrt(summary(update(modello,y~x1+x2))$r.squared)
o, tpiù brevemente ancora:
> sqrt(summary(update(modello,.~.+x2))$r.squared)
Naturalmente desiderando ridefinire il modello in modo permanente si potrà ricorrere
ad un assegnazione del tipo modello<-update(modello,. .+x2).
È appena il caso di ricordare che, qualora l’oggetto di classe lm fosse definito in base
ad una formula, questa può essere “aggiornata”, nel senso di cui sopra, ricorrendo
all’istruzione update.formula().
Esempio 6.5.4 Con riferimento alla situazione di cui all’Esempio 6.3.1, definito, per il
modello di regressione Y = β0 + β1 X1 + *, l’oggetto di classe lm:
> modello<-lm(Risposta~x1,data=dati)
la frazione della varianza totale di Y spiegata dal modello, ovvero R 2 , è circa il 68%, infatti:
186
E. D. Isaia, Linguaggio R e applicazioni statistiche
> summary(modello)$r.squared
[1] 0.6796644
L’introduzione nel modello del secondo predittore X2 riduce ulteriormente tale indicatore e
precisamente del 21%, risultando:
> summary(update(modello,.~.+x2))$r.squared
[1] 0.8933146
A tal proposito si osservi il comportamento delle istruzioni:
> formula<-as.formula(Risposta~x1)
> summary(lm(formula,data=dati))$r.squared
[1] 0.6796644
> summary(lm(update.formula(formula, ~ . + x2),data=dati))$r.squared
[1] 0.8933146
che evidentemente porgono gli stessi risultati.
6.5.3
♥
Sulla multicollinearità e la stepwise regression
Come si è già osservato, in alcune situazioni, può accadere che i test sui parametri
βj conducano all’accettazione delle ipotesi nulle e ciò indipendentemente dal valore
assunto da R2 . Una delle possibili cause di tale comporamento è imputabile alla
varianza delle stime, la quale, come si accennò al paragrafo 6.4.4, viene a sua volta
dipendere dalla matrice di correlazione tra le variabili esplicative. Nel caso, dunque,
di multicollinearità, si può tentare di pervenire ad un modello di regressione stabile
operando discrezionalmente sul numero dei predittori da inserire nel modello stesso.
L’Esempio che segue presenta un semplice problema di regressione multipla in presenza di multicollarineità tra i predittori, risolvibile effettuando una selezione “manuale”
delle variabili esplicative.
Esempio 6.5.5 Un campione casuale di n = 10 autovetture di piccola cilindrata ad alimentazione a benzina ha fornito i seguenti risultati in corrispondenza a quattro variabili di
interesse:
Cilindrata
Potenza
Peso
Consumi
(cc)
(cv.Din)
(kg)
1075
1255
1075
1306
1455
1055
1175
1175
1375
1255
45
62
45
72
60
53
57
54
72
75
750
805
710
805
820
850
755
815
810
805
(l × 100)
187
5.0
6.5
4.8
6.7
6.5
6.3
4.8
5.9
6.4
6.5
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Desiderando spiegare il Consumo di carburante in funzione
dei tre predittori, scegliamo di
(3
ricorrere al modello di regressione multipla Y = β0 + j=1 βj Xj + *.
Dal punto di vista pratico, inserite le osservazioni campionarie nel data frame auto e definito
il modello di regressione a tre predittori:
> auto<-data.frame(
Cilindrata=c(10.75, 12.55, 10.75, 13.06, 14.55, 10.55,
11.75,11.75, 13.75, 12.55)*100,
CV.Din=c(45, 62, 45, 72, 60, 53, 57, 54, 72, 75),
Peso=c(750, 805, 710, 805, 820, 850, 755, 815, 810, 805),
Consumo=c(5, 6.5, 4.8, 6.7, 6.5, 6.3, 4.8, 5.9, 6.4, 6.5))
> modello<-lm(Consumo~.,data=auto)
otteniamo17 i seguenti risultati:
> summary(modello)$coefficients
Estimate Std. Error t value
(Intercept) -5.7378368
2.288926 -2.5068
Cilindrata
0.0009164
0.001188 0.7713
CV.Din
0.0230951
0.015522 1.4879
Peso
0.0115907
0.003114 3.7221
Pr(>|t|)
0.046103
0.469800
0.187354
0.009828
sicché saremo propensi ad accettare le ipotesi nulle circa i coefficienti β1 e β2 . Tuttavia, tale
soluzione non è certo soddisfaciente! La natura stessa dei predittori Cilindrata e Potenza fa
sı̀ che essi siano correlati tra loro, ed infatti18 :
> (R<-cor(model.matrix(update(modello,.~.-1))))
Cilindrata
CV.Din
Peso
Cilindrata
1.0000
0.7167
0.4091
CV.Din
0.7167
1.0000
0.5015
Peso
0.4091
0.5015
1.0000
donde i fattori di inflazione della varianza (VIF):
> (vif<-diag(solve(R)))
[1] 2.070 2.303 1.345
nonché i coefficienti di correlazione multipla tra i predittori:
> 1-(1/vif)
[1] 0.5170 0.5658 0.2566
Si noti che questi ultimi potrebbero essere calcolati in modo diretto ricorrendo, ad esempio,
all’istruzione:
17
18
Ipotizzando la normalità del termine di disturbo.
Per una migliore leggibilità dei risultati, si è scelto di porre options(digits=4).
188
E. D. Isaia, Linguaggio R e applicazioni statistiche
> cbind(summary(update(modello,Cilindrata~CV.Din+Peso))$r.squared,
summary(update(modello,CV.Din~Cilindrata+Peso))$r.squared,
summary(update(modello,Peso~Cilindrata+CV.Din))$r.squared)
[,1]
[,2]
[,3]
[1,] 0.517 0.5658 0.2566
Ciò premesso, possiamo pensare di eliminare una delle due variabili esplicative al modello e
ri-sottoporre a verifica i parametri dello stesso.
> summary(update(modello,.~Cilindrata+Peso))$coefficients
Estimate Std. Error t value Pr(>|t|)
(Intercept) -6.963191 2.3133772 -3.010 0.019663
Cilindrata
0.002062 0.0009802
2.103 0.073507
Peso
0.013107 0.0031873
4.112 0.004502
> summary(update(modello,.~CV.Din+Peso))$coefficients
Estimate Std. Error t value Pr(>|t|)
(Intercept) -5.23809
2.130841 -2.458 0.043579
CV.Din
0.03085
0.011476
2.689 0.031152
Peso
0.01179
0.003012
3.913 0.005798
Un’attenta lettura dei risultati, ci porta a ritenere che il Consumo possa essere “spiegato”
mediante le varibili Peso e Potenza.
Si noti che saremmo giunti alle stesse conclusioni valutando:
— la frazione della varianza spiegata dai due modelli a due predittori:
> summary(update(modello,.~Cilindrata+Peso))$r.squared
[1] 0.8298
> summary(update(modello,.~CV.Din+Peso))$r.squared
[1] 0.8633
— la sitma della varianza σ 2 offerta dai due modelli a due predittori:
> summary(update(modello,.~Cilindrata+Peso))$sigma
[1] 0.3605
> summary(update(modello,.~CV.Din+Peso))$sigma
[1] 0.3230
♥
Il problema della identificazione dei predittori nel caso di multicollinearità può essere
affrontato, come si disse al paragrafo 6.4.4, ricorrendo alla stepwise regression, tenica
implementata in R quale funzione step, la cui sintassi, perlomeno nella sua veste più
dimessa, è:
step(modello, trace=1, test="F")
189
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
A tal proposito è bene tenere a mente che:
— modello è un oggetto di classe lm definito via lm(formula=..., ...);
— con l’opzione trace=0 viene soppressa la visualizzazione dei passi intermedi che
conducono al modello definitivo; la situazione di default prevede trace=1;
— l’opzione test="F" stabilisce quale criterio di selezione dei predittori quello
basato su R2 ;
— in modo automatico, alla fine del processo, vengono elencati i predittori selezionati e le corrispondenti stime dei parametri;
— step(...) è, a sua volta, un oggetto di classe lm e, in quanto tale, per esso
valgono le considerazioni fatte a proposito di tali oggetti. Ad esempio con
model.matrix(step(...,...)) viene visualizzata la matrice X associata al
modello di regressione con i k ≤ p predittori selezionati.
Esempio 6.5.6 Con riferimento alla situazione di cui all’Esempio 6.5.6, la risoluzione del
problema di multicollinearità viene risolta, ricorrendo alla funzione step, mediante le istruzioni:
> step(modello,trace=1,test="F")
Start: AIC= -19.11
Consumo ~ Cilindrata + CV.Din + Peso
Df Sum of Sq
RSS
AIC F value
Pr(F)
- Cilindrata 1
0.0659
0.7303 -20.1685 0.5949 0.469800
<none>
0.6644 -19.1139
- CV.Din
1
0.2451
0.9096 -17.9735 2.2137 0.187354
- Peso
1
1.5342
2.1987 -9.1474 13.8542 0.009828 **
--Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1
‘ ’
1
‘ ’
1
Step: AIC= -20.17
Consumo ~ CV.Din + Peso
Df Sum of Sq
RSS
AIC F value
Pr(F)
<none>
0.7303 -20.1685
- CV.Din 1
0.7541
1.4845 -15.0754 7.2282 0.031152 *
- Peso
1
1.5979
2.3282 -10.5750 15.3151 0.005798 **
--Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
Call:
190
0.1
E. D. Isaia, Linguaggio R e applicazioni statistiche
lm(formula = Consumo ~ CV.Din + Peso, data = auto)
Coefficients:
(Intercept)
-5.23809
CV.Din
0.03085
Peso
0.01179
Per concludere, osserviamo che la matrice delle osservazioni associata al modello di regressione
a due predittori e il data frame contenente le sole realizzazioni delle (tre) variabili di interesse,
possono ottenersi con le istruzioni19 :
> t(model.matrix(step(modello,trace=0,test="F")))
1
2
3
4
5
6
7
8
9 10
(Intercept)
1
1
1
1
1
1
1
1
1
1
CV.Din
45 62 45 72 60 53 57 54 72 75
Peso
750 805 710 805 820 850 755 815 810 805
attr(,"assign")
[1] 0 1 2
> t(model.frame(step(modello,trace=0,test="F")))
1
2
3
4
5
6
7
8
9
10
Consumo
5
6.5
4.8
6.7
6.5
6.3
4.8
5.9
6.4
6.5
CV.Din
45 62.0 45.0 72.0 60.0 53.0 57.0 54.0 72.0 75.0
Peso
750 805.0 710.0 805.0 820.0 850.0 755.0 815.0 810.0 805.0
utili al fine di successive elaborazioni.
6.6
♥
L’analisi della varianza
Una delle tecniche statistiche di impiego più frequente nelle ricerche sperimentali è
rappresentata dall’analisi della varianza (ANOVA); com’è noto, essa consente essenzialmente, a partire da campioni indipendenti estratti da popolazioni con distribuzione
normale, di verificare se le medie delle popolazioni poste a confronto possono essere
ritenute statisticamente uguali, ad un prefissato livello di significatività.
Data la vastità dell’argomento, nel seguito considereremo unicamente l’analisi della
varianza per esperimenti ad uno e due fattori.
In R possiamo procedere in modo diretto all’analisi della varianza ricorrendo al comando aov(formula=,data=). Oltre alla consueta tabella ANOVA riassuntiva, tale
funzione restituisce, sottoforma di lista, una serie piuttosto estesa di risultati che
possono, come vedremo, essere ripresi per ulteriori analisi mirate ***
ANOVA per esperimenti ad un fattore Immaginiamo di voler studiare l’influenza
di un certo fattore A su di una grandezza quantitativa Y . Indicati con a 1 , a2 , . . . , ak
19
Per ovvi motivi si presentano le trasposte delle corrispondenti matrici.
191
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
le varie e distinte condizioni sperimentali (livelli, classi o trattamenti) in cui può
presentarsi il fattore A, organizziamo un esperimento che preveda:
n1
n2
...
nk
misurazioni di Y con il fattore A al livello a 1
misurazioni di Y con il fattore A al livello a 2
......................................
misurazioni di Y con il fattore A al livello a k
È quasi il caso di notare come il problema posto sia analogo a quello di avere a che fare
con k diversi campioni indipendenti, ciascuno di dimensione n i , tratti da altrettante
popolazioni.
Supposto che i k campioni casuali (Y i1 , Yi2 , . . . , Yini ), siano indipendenti e provengano da popolazioni normali con valor medio µ + α i e comune varianza σ 2 , possiamo
introdurre un modello che considera le v.c. Y ij come una combinazione lineare del
tipo Yij = µ + αi + -ij , dove le eij sono v.c. i.i.d. N (0, σ 2 ).
Se i diversi livelli del fattore A influenzano i dati del campione allo stesso modo, è lecito
formulare l’ipotesi nulla che siano uguali i corrispondenti valori medi da sottoporre
a verifica contro l’ipotesi alternativa che almeno due di essi siano diversi tra loro; in
simboli:
+
H 0 : µ1 = µ2 = . . . = µ k = µ0
H1 : ∃ i, j; i 3= j : µi 3= µj
(6.39)
L’ANOVA è lo strumento adatto appunto alla verifica di tali ipotesi statistiche; essa si
basa essenzialmente sul concetto di scissione della devianza di Y nelle due componenti
SSA e SSE ; la prima rappresenta la devianza imputabile ai diversi livelli del fattore
A, la seconda quella derivante dall’effetto di altre cause non esplicitamente prese in
considerazione. Se H0 è vera, SSA dipenderà unicamente dalla varianza σ 2 , mentre
in caso contrario dipenderà, oltre che dalla varianza, anche dai parametri a i . Ai
fini dell’ANOVA è pertanto necessario confrontare tra loro la devianza SS A con la
devianza SSE . Se SSA è significativamente maggiore di SS E , si può concludere che
le quantità ai risultano diverse da zero; in altri termini, il fattore A influenza il valor
medio della v.c. osservata Y , ovvero la popolazione oggetto di studio non è omogenea
rispetto al fattore di classificazione.
Ricordando che il rapporto tra due v.c. χ 2 indipendenti divise per i rispettivi gradi
di libertà ha distribuzione F di Snedecor, l’ANOVA assumerà quale funzione test il
rapporto:
n − k SSA
k − 1 SSE
che, vera H0 , ha appunto distribuzione F di Snedecor con (k − 1) gradi di libertà a
numeratore e (n − k) gradi di libertà a denominatore.
192
E. D. Isaia, Linguaggio R e applicazioni statistiche
Esempio 6.6.1 Si immagini che i dati che seguono rappresentino il risultato di una serie
di misurazioni (espresse in Kg/m2 ) del valore di resistenza a compressione di esemplari di
cemento sottoposti a cinque diversi trattamenti Ai , i = 1, 2, . . . , 5:
A1
59.1
60.2
58.9
60.1
59.3
A2
62.7
62.3
59.9
60.3
59.7
A3
58.9
60.2
59.7
60.5
59.9
A4
60.5
62.0
62.3
59.7
61.4
A5
59.8
60.6
61.7
61.3
60.2
È interessante verificare se i risultati sperimentali ottenuti siano, in media, influenzati dal
particolare tipo di trattamento a cui sono stati sottoposti gli esemplari.
Creato, per comodità, il data frame cemento contenente i risultati sperimentali:
> y<-c(59.1,62.7,58.9,60.5,59.8,60.2,62.3,60.2,62.0,60.6,
58.9,59.9,59.7,62.3,61.7,60.1,60.3,60.5,59.7,61.3,
59.3,59.7,59.9,61.4,60.2)
> a<-factor(c(rep(c(1:5),5)))
> (cemento<-data.frame(tratta=factor(a),risposta=y))
tratta risposta
1
1
59.1
2
2
62.7
3
3
58.9
4
4
60.5
5
5
59.8
..................
21
1
59.3
22
2
59.7
23
3
59.9
24
4
61.4
25
5
60.2
> rm(y,a)
> attach(cemento)
è facile verificare che, per ciascun tipo di trattamento, media e varianza campionarie risultano:
> for (i in 1:length(unique(tratta))){
cat("A=",i," media =>",round(mean(split(risposta,tratta)[[i]]),2),
" varianza =>",var(split(risposta,tratta)[[i]]),"\n")}
A=
A=
A=
A=
A=
1
2
3
4
5
media
media
media
media
media
=>
=>
=>
=>
=>
59.52
60.98
59.84
61.18
60.72
varianza
varianza
varianza
varianza
varianza
=>
=>
=>
=>
=>
0.352
1.992
0.368
1.157
0.607
193
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Verificata l’omoschedasticità delle varianze tramite il test di Bartlett (cfr. paragrafo 5.3):
> bartlett.test(risposta,tratta)
Bartlett test for homogeneity of variances
data: risposta and tratta
Bartlett’s K-squared = 4.1982, df = 4, p-value = 0.3798
> detach(cemento)
se assumiamo che i risultati sperimentali siano determinazioni di altrettanti campioni casuali
Xj ∼ N (µj , σ), ciascuno di cardinalità n = 5, con j = 1, 2, . . . , 5, possiamo procedere alla
verifica delle seguenti ipotesi statistiche:
H0 : µ1 = µ2 = µ3 = µ4 = µ5
H1 : ∃ (i, j)i$=j µi = µj
cioè effettuare un’analisi della varianza ad un solo fattore di classificazione (il tipo di trattamento) sulla grandezza quantitativa Y , la resistenza a compressione.
A tal fine, definiamo l’oggetto my.anova, che conterrà il modello statistico, la sorgente dei
dati e le informazioni di base per la verifica delle ipotesi di interesse, tramite il comando:
> (my.anova<-aov(risposta ~ tratta,data=cemento))
Call:
aov(formula = risposta ~ tratta, data = cemento)
Terms:
tratta Residuals
Sum of Squares 10.6184
17.9040
Deg. of Freedom
4
20
Residual standard error: 0.94615
Desiderando procedere, ovvero calcolare il p − value associato al test, possiamo ricorrere al
comando summary(), il quale coerentemente fornisce:
> summary(my.anova)
Df Sum Sq Mean Sq F value Pr(>F)
tratta
4 10.6184 2.6546 2.9654 0.04486 *
Residuals
20 17.9040 0.8952
--Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’
0.05
‘.’
0.1
‘ ’
1
In sostanza saremo portati (ad un livello di significatività di poco inferiore al 5%) a rifiutare
l‘ipotesi nulla e a ritenere che i diversi tipi di trattamento effettivamente influiscono sulla
capacità di resistenza a compressione del cemento.
Osserviamo che il ricorso al comando model.tables() consente di visualizzare alcune utili
informazioni circa i valori medi campionari; infatti:
194
E. D. Isaia, Linguaggio R e applicazioni statistiche
> model.tables(my.anova, type="means")
Tables of means
Grand mean
60.448
tratta
1
2
3
4
59.52 60.98 59.84 61.18 60.72
5
♥
ANOVA per esperimenti a due fattori senza replicazioni Si immagini, ora, di
voler studiare l’effetto di due fattori, diciamo A e B, su di una certa grandezza quantitativa Y e si supponga che al fattore A siano associati r distinti livelli a 1 , . . . , ai , . . . , ar ,
convenzionalmente detti trattamenti, ed analogamente al fattore B siano associati s
distinti livelli b1 , . . . , bj , . . . , bs , convenzionalmente detti blocchi, di modo che siano
complessivamente possibili r × s differenti condizioni sperimentali. Si ipotizzi, altresı̀, di effettuare per ciascuna combinazione dei livelli dei fattori in esame un’unica
osservazione Yij , con i = 1, 2, . . . , r; j = 1, 2, . . . , s. Tali risultati sperimentali sono
interpretabili come determinazioni campionarie di altrettante v.c. Y ij i.i.d. secondo
una N (µ + αi + βj , σ 2 ).
In altri termini possiamo modellizzare le v.c. Y ij come una combinazione lineare del
tipo Yij = µ + αi + βj + -ij , dove µ indica il valor medio di Y , mentre α i = µi. − µ
e βj = µ.j − µ rappresentano, rispettivamente l’effetto del i-esimo trattamento e del
j-esimo blocco e le -ij sono v.c. i.i.d. N (0, σ 2 ).
Se i diversi livelli del fattore A influenzano Y nella stessa misura, è lecito formulare
(1)
l’ipotesi che i diversi trattamenti abbiano ugual valor medio, cioè H 0 : αi = 0, ∀ i da
(1)
sottoporre a verifica contro l’ipotesi alternativa H 1 : ∃ i : αi 3= 0. In modo del tutto
analogo, per il fattore B possiamo ipotizzare che i diversi blocchi abbiano ugual valor
(2)
medio, ovvero H0 : βj = 0, ∀ j da sottoporre a verifica contro l’ipotesi alternativa
(2)
H1 : ∃ j : βj 3= 0. Riasumendo consideriamo i seguenti sistemi di ipotesi:
O
O
(1)
H0 : αi = 0
(1)
H1 : ∃ i : αi 3= 0
(6.40)
(2)
H0 : βj = 0
(2)
H1 : ∃ i : βi 3= 0
(6.41)
Anche in questo caso, con opportuni passaggi, si può scindere la devianza totale di
Yij nei tre addendi SSA , SSB e SSE , che rappresentano, rispettivamente, la devianza
tra i trattamenti, la devianza tra i blocchi e la devianza residua.
195
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Il procedimento per verificare le ipotesi statistiche precedentemente poste, si basa
(1)
(2)
sulla seguente osservazione: se H 0 e H0 sono vere, SSA e SSB dipendono unicamente da σ 2 , mentre in caso contrario dipenderanno anche dai parametri α i e βj
rispettivamente.
Ai fini dell’ANOVA si tratterà, pertanto, di confrontare le devianze SS A e SSB
rispetto a SSE . Le funzioni test atte a tal fine sono:
SSA
r−1
SSE
(r − 1) (s − 1)
SSB
s−1
SSE
(r − 1) (s − 1)
che, vere le corrispondenti ipotesi nulle, si ditribuiscono secondo una F di Snedecor
con, rispettivamente, (r − 1) e (s − 1) gradi di libertà a numeratore e (r − 1) · (s − 1)
gradi di libertà a denominatore.
Esempio 6.6.2 Si immagini che al fine di una simulazione numerica siano state approntate
tre routine di calcolo (r1 , r2 , r3 ), ciascuna delle quali redatta in accordo a tre diversi algoritmi;
al fine di verificare la velocità di esecuzione (Y ), si è fatto ricorso ad un esperimento che
prevedeva la misurazione dei tempi di esecuzione (in secondi) delle tre routine (fattore A a tre
livelli) su altrettanti PC (fattore B a tre livelli o blocchi),con uguali caratteristiche, ottenendo
i seguenti risultati sperimentali:
Routine ↓ Pc →
r1
r2
r3
pc1
2.42
2.45
2.46
pc2
2.44
2.44
2.47
pc3
2.43
2.46
2.48
Trattasi evidentemente di un esperimento a due fattori (A,B) a tre livelli ciascuno con una
sola replicazione per cella.
Procedendo, creiamo, per comodità, il data frame dati contenente i risultati sperimentali:
>
>
>
>
1
2
3
4
5
6
7
8
9
>
y<-c(2.44,2.42,2.43,2.45,2.44,2.46,2.46,2.47,2.48)
a<-factor(c(1,1,1,2,2,2,3,3,3))
b<-factor(c(1,2,3,1,2,3,1,2,3 ))
(dati<-data.frame(fattoreA=a,fattoreB=b,risposta=y))
fattoreA fattoreB risposta
1
1
2.44
1
2
2.42
1
3
2.43
2
1
2.45
2
2
2.44
2
3
2.46
3
1
2.46
3
2
2.47
3
3
2.48
rm(a,b,y)
196
E. D. Isaia, Linguaggio R e applicazioni statistiche
e successivamente, al fine di verificare le ipotesi statistiche (6.40) e (6.41), definiamo l’oggetto
my.anova, che conterrà il modello statistico, la sorgente dei dati nonché le informazioni di
base per la verifica delle ipotesi di interesse, tramite il comando:
> (my.anova<-aov(risposta ~ fattoreA+fattoreB,data=dati))
Call:
aov(formula = risposta ~ fattoreA + fattoreB, data = dati)
Terms:
fattoreA
fattoreB
Residuals
Sum of Squares 0.0024000000 0.0002666667 0.0003333333
Deg. of Freedom
2
2
4
Residual standard error: 0.00912871
A questo punto ricorrendo al comando summary(), otteniamo i risultati desiderati:
> summary(my.anova)
Df
Sum Sq
fattoreA
2 0.00240000
fattoreB
2 0.00026667
Residuals
4 0.00033333
--Signif. codes: 0 ‘***’
Mean Sq F value Pr(>F)
0.00120000
14.4 0.01487 *
0.00013333
1.6 0.30864
0.00008333
0.001
‘**’
0.01
‘*’
0.05
‘.’
0.1
‘ ’
1
Risultati che ci portano a ritenere che le tre routine abbiano, perlomeno dal punto di vista sta(1)
tistico, un diverso comportamento (si rifiuta H0 ), mentre, come auspicabile, non emergono
(2)
differenze significative circa il comportamento dei PC (si accetta H0 ).
♥
ANOVA per esperimenti a due fattori con replicazioni Nello schema di classificazione illustrato al punto precedente si assumeva l’assenza di interazione tra i
fattori A e B. Per potere individuare la presenza di un’eventuale interazione tra
i fattori, è necessario disporre di più osservazioni per ciascuna delle r × s situazioni sperimentali. Nel seguito supporremo che ogni cella contenga un ugual numero
n > 1 di osservazioni, sı̀ che risultati sperimentali possano essere indicati Y ijk , dove
k = 1, 2, . . . , n rappresenta la k-esima osservazione relativa alla ij-esima cella. Possiamo affermare che i valori sperimentali costituiscono determinazioni campionarie di
altrettante v.c. Yijk i.i.d. N (µ + αi + βj + λij , σ 2 ). Ricordando che µij. = E[Ȳij. ],
µi.. = E[Ȳi.. ], µ.j. = E[Ȳ.j. ], µ = E[Ȳ... ], possiamo esprimere le v.c. Yijk quale combinazione lineare Yijk = µ + αi + βj + λij + -ijk , dove αi = µi.. − µ rappresenta l’effetto
del i-esimo livello del fattore A, βj = µ.j. − µ quello del j-esimo livello del fattore B,
λij = µij. − µi.. − µ.j. + µ quello dell’effetto congiunto del i-esimo livello del fattore A
e del j-esimo livello del fattore B, mentre - ijk sono v.c. i.i.d. N (O, σ 2 ).
197
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Le ipotesi statistiche che sottoponiamo a verifica saranno dunque:
H02 : αi = 0, ∀ i
H12 : ∃ i : αi 3= 0
(6.42)
H02 : βj = 0, ∀ j
H12 : ∃ j : βj 3= 0
(6.43)
H03 : λij = 0, ∀ i, j
H13 : ∃ i, j; i 3= j : λij 3= 0
(6.44)
Anche in questo caso, con opportuni passaggi, si può scindere la devianza totale di
Yijk nei quattro addendi SSA , SSB , SSAB e SSE , che rappresentano, rispettivamente, la devianza tra i trattamenti, la devianza tra i blocchi, la devianza imputabile
all’interazione fra trattamenti e blocchi e la devianza residua.
Ai fini dell’ANOVA si tratterà di confrontare le devianze SS A , SSB e SSAB rispetto
a SSE ; le statistiche test atte a tal fine sono:
SSAB
(r − 1) (s − 1)
SSE
r s (n − 1)
SSB
s−1
SSE
r s (n − 1)
SSA
r−1
SSE
r s (n − 1)
che, vere le corrispondenti ipotesi nulle, si ditribuiscono secondo una F di Snedecor
con, rispettivamente, (r − 1), (s − 1) e (r − 1) · (s − 1) gradi di libertà a numeratore
e r s (n − 1) gradi di libertà a denominatore.
Esempio 6.6.3 I responsabili del Controllo di Qualità di un importante lanificio ritengono
che le proprietà meccaniche e dimensionali (individuabili ricorrendo a specifici parametri)
del tessuto siano influenzate, nel corso del processo di decantissaggio in autoclave, da due
particolari fattori; la posizione (fattore A) del tessuto all’interno del cilindro di decantissaggio
e la differenza (fattore B) fra pezza e pezza di uno stesso tipo di tessuto. Per verificare
tale convinzione venne progettato un esperimento che prevedeva la misurazione dei succitati
parametri su campioni di stoffa prelevati casualmente in corrispondenza a diverse combinazioni
dei due fattori A e B. In particolare, per ciascun fattore si sono considerati tre livelli e per
ciascuna delle nove condizioni sperimentali si sono effettuate cinque misurazioni. Trattasi,
manifestamente, di un esperimento a due fattori di classificazione con un ugual numero di
osservazioni per cella, di cui il fattore A costituisce il fattore di interesse dell’indagine mentre
il fattore B esprime la variabilit, non eliminabile, del processo produttivo. Le ipotesi che si
vogliono verificare, limitatamente alla sola grandezza di interesse Y sono:
(1)
H0 :
(2)
H0 :
(3)
H0 :
il fattore A non ha alcuna influenza su Y ;
il fattore B non ha alcuna influenza su Y ;
non esiste interazione tra i fattori A e B.
sulla base delle seguenti realizzazioni sperimentali:
198
E. D. Isaia, Linguaggio R e applicazioni statistiche
A
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
B
1
1
1
1
1
2
2
2
2
2
3
3
3
3
3
Y
476
474
465
477
490
481
487
492
485
469
490
486
473
475
479
A
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
B
1
1
1
1
1
2
2
2
2
2
3
3
3
3
3
Y
517
499
501
503
485
491
501
487
504
498
514
495
506
525
503
A
1
1
1
1
1
2
2
2
2
2
3
3
3
3
3
B
513
483
507
504
483
501
517
505
495
510
533
514
525
510
504
Y
> y<-c(476,474,465,477,490,481,487,492,485,469,490,486,473,475,479,
517,499,501,503,485,491,501,487,504,498,514,495,506,525,503,
513,483,507,504,483,501,517,505,495,510,533,514,525,510,504)
> a<-c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3)
> b<-c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,
1,1,1,1,1,2,2,2,2,2,3,3,3,3,3)
> dati<-data.frame(fattoreA=factor(a),fattoreB=factor(b),risposta=y)
> my.anova<-aov(risposta ~ fattoreA+fattoreB+fattoreA*fattoreB,data=dati)
porgono la seguente tabella ANOVA:
> summary(my.anova)
Df Sum Sq Mean Sq F value
Pr(>F)
fattoreA
2 6190.0 3095.0 30.1690 2.019e-08 ***
fattoreB
2 844.9
422.5 4.1181
0.02452 *
fattoreA:fattoreB 4 586.7
146.7 1.4297
0.24407
Residuals
36 3693.2
102.6
--Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
0.1
‘ ’
1
In sostanza siamo portati a credere che i due fattori A e B influenzano singolarmente, ma non
congiuntamente la grandezza Y in esame.
♥
199
Capitolo 7
Elementi di simulazione *** da rifare
Affrontiamo, ora, alcuni specifici problemi connessi alla simulazione. Si tratta di
semplici esempi di specie che tendono ad illustrare, ancora una volta, le potenzialità
del linguaggio di programmazione.
7.1
Sul lancio simultaneo di n monete
Con riferimento ad un esperimento casuale che consiste nel lancio simultaneo di n ≥ 1
monete, il numero di Teste apparse può essere descritto mediante una v.c. X che, per
cose note, possiede distribuzione binomiale di parametri n e p, per x = 0, 1, . . . , n.
Nel seuito ci proponiamo di simulare la ripetizione, poniamo k > 1 volte, di tale
esperimento casuale e di ottenere la distribuzione di frequenze empirica del numero
di Teste apparse ad ogni lancio.
A tal fine definiamo la seguente funzione lancio i cui input sono k, n e p:
1
2
3
4
5
6
7
8
9
> lancio<-function(k,n,p,graph=FALSE)
{
x<-sort(rbinom(k,n,p))
fi<-diag(table(x,x))
lancio.out<<-list(n.teste=x,detx=unique(x),freq=fi)
if(graph)
plot(unique(x),fi,type="h",xlim=c(-1,max(unique(x))+1),
xlab="Determinazioni x",ylab="Frequenze empiriche")
}
A commento:
— in riga [3] viene definita e generata la sequenza delle determinazioni di X in
ciascuna delle k repliche dell’esperimento;
E. D. Isaia, Linguaggio R e applicazioni statistiche
— in fi immettiamo le frequenze corrispondenti ad ogni valore di xi (riga [4]). Si
noti il ricorso all’istruzione table di cui si considerano i valori appartenenti alla
sola diagonale principale, essendo nulli altrove;
— in riga [5] viene creata la lista lancio.out contenente i risultati della simulazione;
— in riga [7] viene proposto, a patto che graph=TRUE, il grafico della distribuzione empirica; si noti che unique(x) porge, in ordine crescente, le possibili
determinazioni x = 0, 1, . . . , n di X in ciascuna prova.
Cosı̀, ad esempio:
>
>
0
1
lancio(20,5,.5,graph=FALSE)
lancio.out$freq
1 2 3 4 5
3 4 5 5 2
simula il lancio, ripetuto 20 volte, di cinque monete regolari.
7.2
Sulle catene di Markov
Si immagini che un gioco consista nel lancio di una moneta e che in caso si ottenga
Testa si vincano 100 lire, mentre in caso contrario se ne perdano 100 e che inoltre il
gioco abbia termine non appena si siano perse o guadagnate 500 lire. È interessante
indagare sui tempi di durata gioco, o perlomeno farsi un’idea della durata media
dello stesso. Se, accanto alla v.c. X che indica il numero di Teste ottenute dal lancio,
introduciamo le v.c.:
g(Xt ) =
+
−100
+100
Xt = Croce
Xt =Testa
Ct =
+
0
Ct−1 + g(Xt)
t=0
t = 1, 2, . . .
possiamo modelizzare il gioco quale catena di Markov a tempi discreti definita sugli
stati Ei per cui Ct = i, con i = −5, −4, . . . , 4, 5. Gli stati E−5 ed E5 , in accordo alle
premesse fatte, sono di tipo assorbente, mentre i restanti sono transienti.
La catena proposta, a ben vedere, è la modellizzazione di un ben noto processo stocastico abitualmente detto “passeggiata casuale tra due barriere assorbenti” che si
presta, anche in forme alternative a quella presentata, a diverse applicazioni anche in
campo economico ed industriale.
Se si osserva, poi, che i passaggi tra gli stati E i a Ei+1 o ad Ei−1 avvengono con
probabilità p e 1 − p rispettivamente, la matrice dei transizione del primo ordine
201
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
della catena, avendo cura di riordinare gli stati come E −5 , E5 , E−4 , . . . , E4 , verrà ad
assumere la forma:

1
 0

1 − p

 0


 0


P= 0
 0


 0

 0


 0
0
0 0
0
0
0
0
0
0
0
1 0
0
0
0
0
0
0
0
0 0
p
0
0
0
0
0
0
0 1−p 0
p
0
0
0
0
0
0 0 1−p 0
p
0
0
0
0
0 0
0 1−p 0
p
0
0
0
0 0
0
0 1−p 0
p
0
0
0 0
0
0
0 1−p 0
p
0
0 0
0
0
0
0 1−p 0
p
0 0
0
0
0
0
0 1−p 0
p 0
0
0
0
0
0
0 1−p
In sostanza la matrice P può essere vista come:
P=
:
R S
W Q

0
0

0

0

0


0

0


0

0

p

0
<
dove Q ne rappresenta cosidetta “matrice fondamentale”.
Desiderando indagare sulla durata media della “passeggiata”, tralasciando volutamente la ricerca di una soluzione analitica che potremmo individuare ricorrendo ad
un’equazione alle differenze con opportuni vincoli, sfruttiamo il seguente risultato, dovuto a Brook, Evans (1982), che consente, appunto di ottenere il vettore dei momenti
primi della v.c. TEi che rappresenta il numero di transizioni che occorrono, partendo
da un prefissato stato “iniziale” non transiente E i , i = −4, . . . , 4,, per raggiungere
uno degli stati assorbenti:
µEi = (I − Q)−1 1
Ancor più interessante è analizzare il comportamento di µ Ei , abitualmente detto Average Run Length, al variare di p, cioè sotto l’ipotesi di non correttezza della moneta.
A tal fine è suffficiente far variare i valori di p in (0, 1) o meglio, per la simmetria, in
(0.5, 1).
Per il nostro scopo, ricordando che concentriamo la nostra attenzione al valor medio
di TE0 , sono sufficienti le istruzioni che seguono:
1
2
3
> n<-51; p<-.5; q<-1-p
> I <- matrix(0,nrow=9,ncol=9); I[row(I)==col(I)] <- 1
> one<-cbind(diag(I))
202
E. D. Isaia, Linguaggio R e applicazioni statistiche
4
5
6
7
8
9
10
11
12
13
14
15
16
> arl<-real(n)
> for (i in 1:n){
Q<-matrix(c(0,q,0,0,0,0,0,0,0,p,0,q,0,0,0,0,0,0,
0,p,0,q,0,0,0,0,0,0,0,p,0,q,0,0,0,0,0,0,0,p,0,q,0,0,0,
0,0,0,0,p,0,q,0,0,0,0,p,0,0,p,0,q,0,0,0,0,0,0,0,p,0,q,
0,0,0,0,0,0,0,p,0),nrow=9,ncol=9)
W<-((solve(I-Q))%*%one)
arl[i]<-(((solve(I-Q))%*%one))[5,]
p<-p+0.01; q<-1-p}
> plot(seq(.5,1,by=0.01),arl,type="p",main="",ylab=" A.R.L.",
xlab="p=P[X=1]",col="blue")
> lines(seq(.5,1,by=0.01),arl,col="red")
> grid()
A commento, osserviamo:
— in riga [2] e [3] definiamo la matrice identità (9x9) ed il vettore colonna unitario;
— in riga [4] definiamo l’oggetto arl che conterrà le soluzioni desiderate;
— dalla riga [5] alla [12] vi è il ciclo di calcolo vero e proprio. Si noti che arl dovrà
contenere il valor medio relativo allo stato E 0 , cioè il quinto elemento dei vettori
(I − Q)−1 1 via via calcolati.
I risultati ottenuti per i valori di p = 0.50, (0.01), 1 sono:
340.000
61.042
27.579
16.500
11.460
8.729
7.074
5.982
5.210
214.880
51.813
24.963
15.406
10.892
8.397
6.862
5.835
5.102
151.775
44.665
22.741
14.430
10.377
8.092
6.663
5.697
5.000
114.447
39.005
20.837
13.561
9.909
7.808
6.477
5.565
90.155
34.436
19.192
12.784
9.481
7.546
6.302
5.441
73.297
30.691
17.762
12.088
9.089
7.302
6.137
5.322
mentre in figura (7.1) se ne riporta il grafico.
7.3
Sul teorema limite centrale
Immaginiamo di estrarre k > 1 campioni di numerosità n da una specifica densità
f (x), di calcolare, per ciascuno di essi, il valor medio x̄ e quindi rappresentare graficamente la distribuzione empirica di X̄, che sappiamo distribuirsi asintoticamente
secondo una N (µ, σk −1/2 ) e ciò indipendentemente dalla forma di f (x).
203
200
150
0
50
100
A.R.L.
250
300
350
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
0.5
0.6
0.7
0.8
0.9
1.0
p=P[X=1]
Figura 7.1: Numero medio di giocate al variare di p in (0.5, 1)
A titolo di esempio, posto:
densità
f (x) = 2−1 , 0 < x < 2
n
5
k
2000
il problema può essere risolto semplicemente ricorrendo alle istruzioni:
>
>
>
>
k<-2000
medie.x<-real(k)
for (i in 1:k) {x<-runif(5,0,2); medie.x[i]<-mean(x)}
hist(medie.x,breaks=20,freq=FALSE,main="",xlab="Medie campionarie",
ylab="Frequenze empiriche",col="lightgray",xlim=c(0,2))
In figura (7.2) è riportato l’istogramma dei risultati dalla simulazione.
Una variante, lasciando al Lettore il “gusto” della programmazione, potrebbe essere
quella di ripetere la simulazione proposta per diversi valori di k.
A titolo di esempio in figura (7.3) riportiamo i risultati di una simulazione caratterizzata da:
204
1.0
0.5
0.0
Frequenze empiriche
1.5
E. D. Isaia, Linguaggio R e applicazioni statistiche
0.0
0.5
1.0
1.5
2.0
Medie campionarie
Figura 7.2: Distribuzione delle medie campionarie
densità
f (x) = 2−1 , 0 < x < 20
7.4
n
5
k
10i , i = 1, 2, 3, 4
Sulla funzione di ripartizione empirica
Dato un campione casuale ordinato (X(1) , X(2) , . . . , X(n) ) tratto da una v.c. X, la
funzione di ripartizione empirica o campionaria, F n (x), è definita:
Fn (x) =

0
i/n

1
x < X(1)
X(1) ≤ x < X(n)
x ≥ X(n)
Evidentemente trattasi di una funzione a “scalini” che si avvicina alla funzione di
ripartizione F (x) della v.c. X; nel caso sia vera l’ipotesi che il campione provenga da
X, le differenze Fn (x) − F (x) sono da attribuirsi unicamente al caso.
Per inciso, osserviamo che tali considerazioni costituiscono la base dei cosiddetti test basati sulla funzione di distribuzione empirica (EDF test), tra i quali merita un
205
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
1.0
1.5
2.0
1.5
1.0
0.5
2.0
0.0
0.5
1.0
1.5
Medie campionarie
k=1000
k=10000
1.0
1.5
2.0
1.0
0.5
0.0
Frequenze empiriche
1.0
0.5
0.5
0.0
Medie campionarie
2.0
1.5
Medie campionarie
0.0
0.0
0.0
Frequenze empiriche
1.5 2.0
1.0
0.5
0.5
1.5
0.0
Frequenze empiriche
k=100
0.0
Frequenze empiriche
k=10
0.5
1.0
1.5
2.0
Medie campionarie
Figura 7.3: Distribuzione delle medie campionarie
posto, per cosı̀ dire, di primo piano, perlomeno dal punto di vista storico, quello di
Kolmogorov-Smirnov.
Riprendendo in parte quanto detto in (7.3), la funzione di ripartizione empirica della
(
v.c. media campionaria, X̄ = k −1 ki=1 X̄i , dovrebbe, per k ↑ ∞, avvicinarsi a quella
di una N (µ, σk −1/2 ).
A titolo illustrativo, si immagini di aver tratto k > 1 campioni di numerosità n da
una distribuzione Uniforme in (80, 120) e di aver calcolato, per ciascuno di essi, il
valor medio x̄ e di volere rappresentare graficamente sia la funzione di ripartizione
empirica Fk (x̄) sia quella di una N (µ = 100, 10k −1/2 ).
A tal fine, scelto arbitrariamente di porre k = 30 ed n = 20, sono sufficienti le seguenti
istruzioni:
> k<-30
> n<-20
206
E. D. Isaia, Linguaggio R e applicazioni statistiche
>
>
>
>
>
>
>
medie.x<-real(k)
Femp<-real(0)
for (i in 1:k) {medie.x[i]<-mean(runif(20,80,120))}
medie.x<-sort(medie.x)
Fteor<-pnorm(medie.x,100,10/sqrt(k))
for (i in 1:k){Femp<-append(Femp,i/k)}
plot(medie.x,Femp,type="s",main="",ylab="Funzione di ripartizione
empirica e teorica",xlab="Determinazioni campionarie",col="blue")
> lines(medie.x,Fteor,col="red")
> grid()
1.0
0.8
0.6
0.4
0.2
0.0
Funzione di ripartizione empirica e teorica
L’andamento delle due funzioni di ripartizione è proposto in figura (7.4).
96
98
100
102
104
Determinazioni campionarie
Figura 7.4: Funzioni di ripartizione empirica e teorica
207
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
7.5
Sul bootstrap
Nel seguito descriviamo come sia possibile raggiungere alcuni semplici risultati concernenti la tecnica bootstrap. Tale tecnica non-parametrica, com’è noto, viene applicata
ad uno stimatore θ̂(x1 , x2 , . . . , xn ) mediante il ricampionamento con rimessa effettuato k > 1 volte della n−pla campionaria osservata (x 1 , x2 , . . . , xn ) in modo da ottenere
altrettanti campioni bootstrap (x∗1 , x∗2 , . . . , x∗n ) su ciascuno dei quali verrà calcolato
θ̂ ∗ = θ̂(x∗1 , x∗2 , . . . , x∗n ). La distribuzione dei valori θ ∗ servirà quale base per la stima
del parametro θ.
Per maggiori ragguagli, il Lettore può consultare il testo, assai ricco di spunti ed
esempi applicativi, di Efron, Tibshirani (1993).
Vediamo ora come sia possibile applicare tale tecnica perlomeno nel caso di stima del
valor medio µ.
Pertanto, dati i seguenti valori campionari:
8.00
8.34
8.45
8.50
8.00
8.35
8.49
8.50
8.00
8.35
8.49
8.50
8.15
8.36
8.49
8.52
8.20
8.40
8.50
8.70
8.25
8.40
8.50
8.75
8.25
8.40
8.50
8.78
8.30
8.40
8.50
7.51
8.30
8.40
8.50
7.75
8.34
8.00
8.50
7.90
definiamo, ora, il massimo numero di itrazioni desiderate (maxloop) e al contempo l’oggetto medie.bootstrap che conterrà, appunto, le medie bootstrap via, via
ottenute, mediante le istruzioni:
> maxloop<-5000; medie.bootstrap<-real(maxloop)
A questo punto, procediamo all’estrazione con rimessa di 5.000 campioni casuali
estratti senza rimessa da (x1 , x2 , . . . , xn ) e, per ciascuno di essi, calcoliamo il valor
medio che inseriamo in media.bootstrap. A ciò sopperisce il ciclo:
> for(i in (1:maxloop))
{
medie.bootstrap[i]<-mean(sample(x,replace=TRUE))
}
> hist(medie.bootstrap,xlim=c(8.1,8.5),breaks=20,main="",
xlab="Medie Boostrap",ylab="Frequenze empiriche",col="lightblue")
In figura (7.5) riportiamo l’istogramma dei risultati ottenuti che sintetizziamo in:
originale
bootstrap
valor medio
8.338
8.340044
deviazione standard
0.2592019
0.04044345
208
errore standard
0.04098342
0.0005719567
400
300
200
100
0
Frequenze empiriche
500
E. D. Isaia, Linguaggio R e applicazioni statistiche
8.1
8.2
8.3
8.4
Medie Boostrap
Figura 7.5: Risultati del bootstrap
209
8.5
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
7.6
La libreria rnotes e gli archivi di dati
Per completezza e a vantaggio dell’utente si è pensato di raccogliere tutte le funzioni presentate nel corso della trattazione nella libreria rnotes posta nella directory ...\library\rnotes\R; parimenti la directory \library\rnotes\data conetiene
tutti gli archivi di dati *** formato ***
7.7
Esercizi vari
Riportiamo nel seguito, in modo piuttosto informale, alcuni esercizi che possono essere
risolti facilmente in R ed offrono, confidiamo, spunto per ulteriori applicazioni.
Esercizio 7.7.1
Calcolare la media aritmetica, la media quadratica e la media armonica dei seguenti valori:
12, 10, 11, 11, 12, 13, 15, 16, 17, 10.
♥
Esercizio 7.7.2
Calcolare la mediana e la varianza dei valori riportati in (7.7.1).
♥
Esercizio 7.7.3
Dato l’oggetto x contenente i primi dieci interi consecutivi, ridefinirlo in modo che esso
contenga gli stessi elementi, la loro media e quindi gli stessi elementi ancora ma ordinati
in senso decrescente.
♥
Esercizio 7.7.4
A partire dalle seguenti osservazioni individuali:
12
10
11
12
13
14
14
13
15
10
12
11
10
11
costruire una tabella di frequenze relative.
♥
Esercizio 7.7.5
Dati i valori {20, 21, 24, 20, 21, 23, 24, 25, 27, 30, 25}, creare un oggetto che contega le frequenze relative cumulate di essi.
♥
Esercizio 7.7.6
Date le seguenti osservazioni individuali:
sesso:
Prov:
M
To
M
To
M
Cn
F
At
F
To
M
At
F
Vc
M
To
F
Cn
F
At
F
AL
costruire una tabella doppia di frequenze relative.
Esercizio 7.7.7
Rappresentare graficamente nel piano (x, y) la funzione y 2 = x2 (1 − x2 ).
210
M
Vc
F
Cn
♥
♥
E. D. Isaia, Linguaggio R e applicazioni statistiche
Esercizio 7.7.8
Rappresentare graficamente nel piano (x, y) la funzione y 2 = x1/2 (1 − x1/2 ).
♥
Esercizio 7.7.9
Dati:
"
x = 0.8 0.2
#


0.2 0.8
Y =  0.3 0.7 
0.5 0.5
calcolare Z = xY e, successivamente, Zxt .
♥
Esercizio 7.7.10
Una mutabile statistica doppia presenta la seguente distribuzione congiunta:
B/A
b1
b2
b3
a1
2
4
10
a2
5
6
9
a3
7
7
6
a4
10
7
4
a5
12
9
2
a6
15
10
1
individuare le distribuzioni marginali dei due caratteri A e B e rappresentarle mediante
un diagramma a torta.
♥
Esercizio 7.7.11
Con riferimento all’Esempio posto in (7.7.10), costruire la tabella doppia delle frequenze
relative.
♥
Esercizio 7.7.12
Con riferimento all’Esempio posto in (7.7.10), individuare le distribuzioni condizionate
A|B = bi , con i = 1, 2, 3.
♥
Esercizio 7.7.13
Le misurazioni del peso (Kg) e dell’altezza (cm) effettuate su un gruppo di individui di
sesso maschile porgono la seguente tabella a doppia entrata:
Altezza/Peso
140-150
150-160
160-150
170-180
180-190
50-60
5
4
2
1
0
60-70
2
12
12
2
0
70-80
1
7
13
8
10
80-90
0
1
11
10
15
Si costruiscano, a partire da essa, le matrici di varianza-covarianza e di correlazione.
♥
Esercizio 7.7.14
Con riferimento alla situazione di cui al punto (7.7.13), si rappresenti nel piano (x, y) la
spezzata di regressione e si proceda, altresı̀ al calcolo di η.
♥
211
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Esercizio 7.7.15
Sia Data la seguente matrice delle varianze-covarianze:


2 1 3
CovX,Y =  1 4 1 
2 1 2
estrarre da essa gli elementi per cui risulta ρX,Y ≥ 0.35.
♥
Esercizio 7.7.16
Si risolva il seguente sistema di equazioni:
O 1.2x + 2.5y − z = 10
2.5x − 1.5y + z
x+y+z
= -10
=0
e si verifichi la correttezza dei risultati ottenuti.
♥
Esercizio 7.7.17
Rappresentare graficamente la funzione di ripartizione di una variabile casuale (v.c.) con
distribuzione Binomiale di parametri n = 10 e p = .5
♥
Esercizio 7.7.18
Rappresentare graficamente le funzioni di densità di probabilità di una v.c. con distribuzione Binomiale di parametri n = 10 e p = .75
♥
Esercizio 7.7.19
Posto X una v.c. con distribuzione Binomiale di parametri n = 50 e p = .15, calcolare la
probabilità attinente agli eventi {0 < X < 20} e {X ≥ 20}.
♥
Esercizio 7.7.20
Si rappresentino graficamente le v.c. χ2 con, rispettivamente, 10, 20, 30 e 40 gradi di
libertà.
♥
Esercizio 7.7.21
Generare un campione casuale di dimensione n = 20 tratto da una densità Normale di
parametri µ = 100 e σ 2 = 25 e calcolarne il valor medio x̄.
♥
Esercizio 7.7.22
Generato un campione casuale di dimensione n = 50 tratto da una densità Uniforme in
(20, 35), costruire l’intervallo di confidenza per il valor medio µ al 98.6%.
♥
Esercizio 7.7.23
Generare un campione casuale di dimensione n = 60 tratto da una densità bimodale.
♥
Esercizio 7.7.24
Con riferimento all’Esempio (7.7.23), si costruisca un’istogramma con 4 (7) (10) classi di
egual modulo e ad esso si sovraimponga il grafico di una Normale di parametri (µ̂, σ̂ 2 )
stimati in base ai valori campoionari ottenuti.
♥
212
E. D. Isaia, Linguaggio R e applicazioni statistiche
Esercizio 7.7.25
I valori che seguono rappresentano i tassi medi di interesse sui obbligazioni triennali
applicati da 29 diverse banche in un periodo di sei mesi:
8.40
8.00
8.33
8.50
8.00
7.56
8.51
8.00
7.57
7.82
8.05
7.71
7.82
8.05
8.55
7.90
8.06
8.57
8.00
8.11
8.65
8.65
8.17
8.00
8.71
8.30
8.00
8.00
8.33
Si costruisca e si visualizzi la funzione di ripartizione empirica Fn (x).
♥
Esercizio 7.7.26
Con riferimento ai dati di cui al punto (7.7.25), si analizzi graficamente la trasformata
“integrale” Y = Fn (x).
♥
Esercizio 7.7.27
Da un’indagine condotta su 100 famiglie residenti in provicia di XX, i rediti mensili netti
sono (x 1000 lit.):
3092.547
3190.741
2973.432
2866.213
3467.562
3261.697
3358.325
3306.863
2871.082
3452.798
3434.806
3285.799
3504.032
3627.119
3265.104
3616.714
3937.908
3469.574
3188.127
3367.155
2883.179
3578.601
2988.463
2970.571
3538.944
2957.559
3689.683
3300.451
3338.512
2870.496
2979.124
3522.844
3056.764
2982.205
3648.595
3143.831
2936.208
3312.634
3467.826
3595.635
3043.293
2907.338
3410.187
3212.386
2849.832
3580.035
3207.700
3132.004
3377.674
3391.259
3056.114
2966.232
3315.047
3492.316
2931.252
3214.972
3514.857
2615.924
3425.463
2860.557
3403.109
3277.373
3363.479
3306.835
3002.333
2979.684
3760.060
3670.399
3792.698
3065.804
3089.623
3593.312
3556.721
3297.671
3153.467
3388.534
3555.429
3048.985
3537.857
3219.749
3481.956
3353.335
3233.259
2970.686
3341.397
3076.497
3050.536
2900.712
3270.383
3126.800
3531.567
3151.945
3344.409
3334.146
3206.523
3883.942
3451.231
3042.290
2866.378
3310.131
Si costruiscano e si visualizzino la funzione di ripartizione empirica Fn (x) e la funzione di
ripartizione di una v.c. Normale con parametri µ = x̄ e σ = s.
“Ad occhio” è plausibile ipotizzare la normalità della distribuzione del reddito sulla base
del campione sorteggiato?
♥
Esercizio 7.7.28
Approntare una funzione che, rispetto ad un vettore di dati x, porga il grafico della curva
di concentrazione del Lorenz con, a lato, il valore dell’indice del Gini.
♥
213
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
Esercizio 7.7.29
Si scriva una funzione che consenta di individuare la matrice delle contingenze delle
seguente tabella a doppia entrata:
B/A
b1
b2
a1
22
4
a2
15
10
a3
10
17
a4
6
27
e si verifichi che essa è a somma nulla.
♥
Esercizio 7.7.30
Si immagini che le misurazioni di una certa grandezza di interesse (Y ) siano influenzate dai
possibili livelli di un fattore (X). Un eseprimento atto a verificare tale ipotesi, ha fornito
i seguenti risultati:
X↓
x1
x2
x3
x4
110.2
111.5
109.7
112.3
Y
109.2
112.1
109.8
111.1
112.0
111.9
110.1
112.2
110.7
111.9
110.2
110.7
111.2
112.0
111.1
111.6
Approntare una funzione che, per ciascun livello del fattore, porga valor medio, scarto
quadratico medio, numero di misurazioni e l’intervallo di confidenza al livello 1 − β1 . ♥
Esercizio 7.7.31
Al fine di analizzare il consumo di carburante (miglia x gallone) di un nuovo tipo di autovettura, è stato approntato un’esperimento che prevedeva l’impiego di quattro autovetture
A, B, C e D ed altrettanti piloti a, b, c e d e l’assegnazione, in ciascuno dei quattro turni
di prove, dei piloti alle autovetture. I risultati ottenuti sono:
turno
1
2
3
4
A
9.44
9.61
9.06
8.71
B
9.83
9.22
9.02
9.02
C
9.02
9.39
9.88
9.23
D
9.68
8.76
8.88
9.73
Si proceda all’analisi della varianza ed alla verifica dell’ipotesi che il consumo di carburante
non sia influenzato dal particolare pilota;
♥
Esercizio 7.7.32
Si approntino due funzioni che consentano la stima dei parametri dei modelli:
—
—
Y = β1 + β I]10,∞) x + *
Y = α + β x2 + *
♥
214
E. D. Isaia, Linguaggio R e applicazioni statistiche
Esercizio 7.7.33
Si costruisca una funzione che simuli il lancio ripetuto poniamo n > 1 volte di una moneta.
Ciò ipotizzando che la moneta sia regolare e sia che essa risulti irregolare.
♥
Esercizio 7.7.34
Si scriva una funzione che consenta di individuare la distribuzione dell’ipotenusa di un
triangolo rettangolo le cui misure dei cateti siano determinazioni di altrettante v.c. i.i.d
secondo una Uniforme di parametri a = 11 e b = 14.
♥
Esercizio 7.7.35
Si immagini di lanciare quattro monete e di ripetere l’esperimento finché: o si ottiene una
sequenza di quattro Teste o quattro Croci, oppure si ottengono in successione due sequenze
contenenti un egual numero di Croci e Teste.
Si appronti una funzione che consenta il calcolo della durata media del gioco, tenendo
conto della possibilità che le monete siano truccate.
(Si modellizzi l’esperimento sottoforma di catena di Markov ...)
♥
Esercizio 7.7.36
Si metta a punto una routine che consenta, mediante la tecnica boostrap, di ottenere una
stima per il parametro ignoto σ e ciò sulla base della n−pla campionaria:
{10.1, 11.0, 10.5, 11.7, 12.5, 10.2, 10.7, 12.9, 12.4}
♥
Esercizio 7.7.37
Con riferimento al punto (7.7.36), si costruisca un intervallo di confidenza per σ al livello
1 − α = .90(.01).95.
♥
215
Bibliografia
BARTLETT, M. S.,Properties of sufficiency and statistical tests, Proceedings of the
Royal Statistical Society, Series A, 160, 268-282, 1937
BELSLEY, D. A., KUH, E., WELSCH, R. E., Regression Diagnostics,John Wiley,
New York, 1980
BOWMAN A.W., AZZALINI A. (1997), Applied Smoothing Techniques for Data
Analysis. The Kernel Approach with S-Plus, Clarendon Press, Oxford
BRENT R., Algorithms for Minimization without Derivatives,
BROOK D., EVANS D.A., An Approach to the Probability Distribution of CUSUM
Run Length, Biometrika, 59, 539-549, 1982 Prentice Hall, Englewood Cliffs, New
Jersey, 1973
CHAMBERS J. M., HASTIE T. J., Statistical models in S, Chapman and Hall, New
York, 1992
CLEVELAND, W. S., LOWESS: A Program for Smoothing Scatterplots by Robust
Locally Weighted Regression, The American Statistician, 35, 54, 1981
COOK, R. D., WEISBERG, S., Residuals and Influence in Regression, Chapman
and Hall, London, 1982
DONGARRA, J. J., BUNCH J. R., MOLER C. B., STEWART G. W., LINPACK
Users Guide, SIAM Publications, Philadelphia, 1978
EFRON B., TIBSHIRANI R., An Introduction to the Bootstrap, Chapman and Hall,
New York, 1993
GARTSIDE P.S., A Study of Methods for Comparing Several Variances, Journal of
The Ametican Statistical Association, 67, 1972
GENTLEMAN E., IHAKA R., Notes on R: A Programming Environment for Data
Analysis and Graphics, Dep. of Statistics, Univeristy of Auckland, 1997
E. D. Isaia, Linguaggio R e applicazioni statistiche
GIBBONS J.D., PRATT, J.W., P-Values: Interpretation and Methodology, The
American Statistician, 29, 1975,
IHAKA R., GENTLEMAN E., R: A Language for Data Analysis and Graphics,
Journal of Computational and Graphical Statistics, 5, 299-314, 1996
MARSAGLIA, G., A Random Number Generator for C, Discussion paper, Usenet
newsgroup ‘sci.stat.math’ on September 29, 1997.
McCULLAGH, P., NELDER, J. A., Generalized Linear Models, Chapman & Hall,
II Edition, New York, 2000.
R Core Team, R Reference Index,The R Core Team, 2000
SAPORTA G., Probabilités, Analyse des Données et Statistique, Édition Technip,
Paris, 1990
SCHERVISH J. M., Theory of Statistics, Springer-Verlag, New York, 1997
SHAO J., Mathematical Statistics, Springer-Verlag, New York, 1999
VENABLES W.N., RIPLEY B.D., Modern Applied Statistics with S-Plus, Springer,
New York, 2nd edition, 1997
VENABLES B., SMITH D., Notes on R: A Programming Environment for Data
Analysis and Graphics, Dep. of Statistics, Univeristy of Adelaide, 1992
WAND M.P., JONES M.C. (1995), Kernel Smoothing, Chapman & Hall, London
WICHMANN, B. A., HILL I. D., Algorithm AS 183: An Efficient and Portable
Pseudo-random Number Generator, Applied Statistics, 31, 188-190, 1982
217
Indice
1 Introduzione ad R
1.1 L’ambiente di lavoro . . . . . . . . . . . . . . . . . . . .
1.2 Primi passi in R . . . . . . . . . . . . . . . . . . . . . .
1.2.1 Creazione di oggetti elementari . . . . . . . . . .
1.2.2 Creazione di oggetti contenenti sequenze regolari
1.2.3 Manipolazione di oggetti elementari . . . . . . .
1.2.4 Operatori aritmetici e funzioni matematiche . . .
1.2.5 Su alcune funzioni statistiche . . . . . . . . . . .
1.2.6 Alcune funzioni di utilità generale . . . . . . . .
1.3 Vettori e Matrici . . . . . . . . . . . . . . . . . . . . . .
1.4 Oggetti complessi . . . . . . . . . . . . . . . . . . . . . .
1.4.1 Liste . . . . . . . . . . . . . . . . . . . . . . . . .
1.4.2 Data frame . . . . . . . . . . . . . . . . . . . . .
1.5 Modalità e struttura di un’oggetto . . . . . . . . . . . .
1.6 Funzioni definibili dall’utente . . . . . . . . . . . . . . .
1.7 Su alcune funzioni matematiche . . . . . . . . . . . . . .
1.8 Lettura e registrazione di archivi . . . . . . . . . . . . .
1.8.1 I comandi scan() e write() . . . . . . . . . . .
1.8.2 I comandi read.table() e write.table() . . .
1.8.3 Il comando data() . . . . . . . . . . . . . . . . .
1.9 Personalizzazione dell’ambiente di lavoro . . . . . . . . .
1.10 Le librerie e loro gestione . . . . . . . . . . . . . . . . .
2 Cenni sulle procedure grafiche
2.1 Funzioni grafiche di “primo livello” . . . . .
2.1.1 Funzione plot(x,y) . . . . . . . . .
2.1.2 Funzione matplot(x,y) . . . . . . .
2.1.3 Funzione hist(x) . . . . . . . . . .
2.1.4 Funzione boxplot(x,y,z,...) . . .
2.1.5 Funzioni qqplot(x,y) e qqnorm(x)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
2
4
4
6
8
11
13
15
24
34
34
36
37
39
44
48
48
49
50
51
53
.
.
.
.
.
.
55
55
55
57
57
58
59
Dipartimento di Statistica e Matematica “Diego de Castro”, nota tecnica 2, 2OO1
2.1.6 Funzione barplot(x) e piechart(x) . . .
2.1.7 Funzione polygon(x,y) . . . . . . . . . . .
2.1.8 Funzione curve(espressione) . . . . . . .
2.1.9 Funzione grid(nx,ny) . . . . . . . . . . . .
2.1.10 La funzione rect(xmin,xmax,ymin,ymax) .
2.1.11 Funzione persp(x,y,z) . . . . . . . . . . .
2.1.12 Funzione pairs(x) . . . . . . . . . . . . . .
2.1.13 Altre funzioni grafiche . . . . . . . . . . . .
Funzioni grafiche di “secondo livello” . . . . . . . .
Parametri grafici . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
59
59
60
60
60
61
62
63
63
64
3 Argomenti di statistica descrittiva
3.1 Mutabili e variabili statistiche univariate . . . . . .
3.1.1 Costruzione di semplici tabelle di frequenze
3.1.2 Rappresentazioni grafiche . . . . . . . . . .
3.1.3 Su alcune misure di sintesi . . . . . . . . . .
3.1.4 Sulla concentrazione . . . . . . . . . . . . .
3.2 Mutabili e variabili statistiche bivariate . . . . . .
3.2.1 Tabelle di frequenze doppie . . . . . . . . .
3.2.2 L’indice di dipendenza chi-quadro . . . . .
3.2.3 L’indice di dipendenza in media . . . . . . .
3.2.4 Sulla correlazione lineare . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
67
68
68
72
80
89
89
89
89
89
89
4 Elementi di calcolo delle probabilità
4.1 Semplici esercizi sul calcolo delle probabilità . . . . . . . . . . . . . . .
4.2 Generazione di numeri pseudo-casuali . . . . . . . . . . . . . . . . . .
4.3 Il campionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
107
110
114
117
5 Elementi di statistica inferenziale
5.1 Intervalli di confidenza per un parametro θ . . . . . . . . . . . . . . .
5.2 Verifica di ipotesi statistiche . . . . . . . . . . . . . . . . . . . . . . . .
5.3 La libreria ctest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
120
120
129
135
6 Alcune note sui modelli lineari
6.1 La regressione lineare semplice: il modello teorico . . . . . . . . . . .
6.2 La regressione lineare . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.1 Stima della retta di regressione in base ai valori campionari .
6.2.2 Verifiche di ipotesi circa i parametri della retta di regressione
6.2.3 Alcune considerazioni circa la previsione . . . . . . . . . . . .
6.2.4 Alcune considerazioni sull’analisi dei residui . . . . . . . . . .
6.3 La regressione lineare semplice in R . . . . . . . . . . . . . . . . . .
155
155
156
157
159
162
163
164
2.2
2.3
2
.
.
.
.
.
.
.
E. D. Isaia, Linguaggio R e applicazioni statistiche
6.4
6.5
6.6
6.3.1 La funzione lm(): definizione del modello di regressione . . . . 164
6.3.2 La funzione lm(): oggetti creati in modo automatico . . . . . . 167
6.3.3 La funzione lm(): verifiche di ipotesi sulle stime . . . . . . . . 168
6.3.4 La funzione predict.lm(): intervalli di confidenza e di previsione171
6.3.5 Per un’analisi dei residui . . . ,. . . . . . . . - . . . . . . . . . . . 173
Sulla regressione multipla: il modello y, X β, σ 2 In . . . . . . . . . . 175
6.4.1 Stima e verifica di ipotesi sui parametri del modello . . . . . . 176
6.4.2 Sul coefficiente di correlazione multipla . . . . . . . . . . . . . 179
6.4.3 Sulla previsione e l’analisi dei residui . . . . . . . . . . . . . . . 181
6.4.4 Sulla multicollinearità . . . . . . . . . . . . . . . . . . . . . . . 182
La regressione multipla in R . . . . . . . . . . . . . . . . . . . . . . . . 183
6.5.1 Definizione del modello e l’istruzione model.matrix(lm(...)) 183
6.5.2 Ridefinizione del modello: l’istruzione update(lm(...)) . . . . 186
6.5.3 Sulla multicollinearità e la stepwise regression . . . . . . . . . . 187
L’analisi della varianza . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
7 Elementi di simulazione *** da rifare
7.1 Sul lancio simultaneo di n monete . .
7.2 Sulle catene di Markov . . . . . . . . .
7.3 Sul teorema limite centrale . . . . . .
7.4 Sulla funzione di ripartizione empirica
7.5 Sul bootstrap . . . . . . . . . . . . . .
7.6 La libreria rnotes e gli archivi di dati
7.7 Esercizi vari . . . . . . . . . . . . . . .
3
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
200
200
201
203
205
208
210
210
Scarica

Universit`a degli Studi di Torino Linguaggio R e