Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
CLaM.EPE
Anno Accademico 2013–2014
Introduzione a R
http://cran.r-project.org
>
1
1.3 Un pò di aritmetica, matematica e logi-
ca...
Gli operatori aritmetici vengono usati in R in modo analogo ad una calco-
latrice: + per l’addizione, - per la sottrazione, * per la moltiplicazione, /
per la divisione e ^ per l’elevamento a potenza. Per definire un’espressione
algebrica è necessario usare le parentesi tonde. Ad esempio,
> 7+2*3
[1] 13
> (7+2)*3
[1] 27
> 3/2^2
[1] 0.75
> (3/2)^2
[1] 2.25
> (2+1)^(1/2)
[1] 1.732051
> sqrt(2+1)
[1] 1.732051
> log(5)
[1] 1.609438
> log10(6)
[1] 0.7781513
> exp(3)
[1] 20.08554
> abs(-5)
[1] 5
> cos(pi)
[1] -1
2
> exp(sqrt(30/2))
[1] 48.08563
Gli operatori di confronto sono: < per minore, > per maggiore, <= per
minore o uguale, >= per maggiore o uguale, == per uguale e != per diverso.
Il confronto restituisce una risposta logica, ad esempio
> 4>2
[1] TRUE
> 4>5
[1] FALSE
> 5!=5
[1] FALSE
> x<-sqrt(2)
> x=sqrt(2)
> x
[1] 1.414214
> x<-4
> x
[1] 4
C’è differenza tra l’uso delle lettere maiuscole e minuscole per i nomi sia
delle variabili che delle funzioni; pertanto, x e X rappresentano due variabili
diverse.
Possiamo assegnare ad una variabile anche valori logici e stringhe di
caratteri
3
> y<-x>5
> y
[1] FALSE
> Y<-x<= 5
> Y
[1] TRUE
> z<-"Esempio"
> z
[1] "Esempio"
Per ottenere l’elenco di tutti gli oggetti presenti nell’area di lavoro si usa
il comando ls():
> ls()
[1] "x" "y" "Y" "z"
Per cancellare una variabile ci si avvale della funzione rm; ad esempio, con
> rm(x)
viene cancellata la variabile x. Per cancellare più di una variabile, basterà
dare come argomento di rm l’elenco delle variabili separate da una virgola.
> rm(y,Y)
> ls()
[1] "z"
4
dati, il nostro lavoro verrà direttamente salvato nel file .RData della directory
mywork.
Per le sessioni successive, se clicchiamo due volte con il mouse sul file
.RData della directory mywork, non solo R verrà avviato automaticamente,
ma caricherà tutti i dati che avevamo precedentemente salvato in .RData e
userà mywork come directory di lavoro. Questo è il metodo consigliato per
l’apertura delle successive sessioni di R .
I comandi dati durante una sessione sono mantenuti in memoria e pos-
sono essere richiamati usando la freccia ‘su’. Se in qualsiasi momento si
vuole salvare il trascritto della sessione, scegliere Save History dal menu Fi-
le. I comandi vengono cosı̀ salvati su un file di testo (tipicamente chiamato
.Rhistory) nella directory di lavoro a cui possiamo accedere per richiamare
comandi dati precedentemente. In alternativa, si può copiare e incollare i
comandi su un file di testo tramite un editor, quale Notepad.
1.6 I vettori
1.6.1 Creazione di un vettore
I vettori possono essere creati in modi diversi. Il più frequente è tramite la
funzione c che esegue una concatenazione degli oggetti elencati:
> x<-c(1,2,3)
> x
[1] 1 2 3
> y<-c(1,6)
> z<-c(x,y)
> z
[1] 1 2 3 1 6
> x<-1:10
> x
[1] 1 2 3 4 5 6 7 8 9 10
> seq(1,9,by=2)
[1] 1 3 5 7 9
5
creiamo un vettore che contiene la successione di numeri da 1 a 9 con un
passo di 2, mentre con
> seq(8,20,length=6)
[1] 8.0 10.4 12.8 15.2 17.6 20.0
creiamo un vettore di lunghezza 6 che contiene la successione di numeri da
8 a 20 (il passo è determinato automaticamente da R per raggiungere la
lunghezza prescelta).
Gli ultimi due esempi mostrano come le funzioni in R possano avere ar-
gomenti opzionali. Ad esempio, per seq sono opzioni la lunghezza del passo,
specificata tramite by, o la lunghezza totale della successione, specificata tra-
mite length (non ha senso usare entrambe). Se le opzioni sono omesse, R
fa una scelta di default. Con seq il default è prendere un passo pari a 1,
cosı̀ seq(1,10) produce lo stesso risultato di 1:10. Per avere dettagli sulle
opzioni disponibili per ogni funzione e sulle scelte di default avvalersi sempre
del Help di R.
Una funzione utile per creare un vettore in cui siano ripetuti degli schemi
è rep. Ad esempio,
> x<-rep(1,10)
> x
[1] 1 1 1 1 1 1 1 1 1 1
> x<-rep(c(1,5),3)
> x
[1] 1 5 1 5 1 5
> y<-c(rep(2,3),4,5,rep(1,5))
> y
[1] 2 2 2 4 5 1 1 1 1 1
I vettori possono essere anche di stringhe di caratteri o logici. Ad esempio,
> y<-c("questo", "e", "un esempio")
> y
[1] "questo" "e" "un esempio"
> z<-c(5<2,3>1,1==0)
> z
[1] FALSE TRUE FALSE
Non è però prevista la possibilità di avere vettori di tipo misto.
6
zioni che hanno come termini dei vettori vengono eseguite componente per
componente. Ad esempio,
> a<-1:5
> a
[1] 1 2 3 4 5
> b<-7:11
> b
[1] 7 8 9 10 11
> a+b
[1] 8 10 12 14 16
Quindi il primo elemento di a viene sommato al primo elemento di b, il
secondo di a al secondo di b e cosı̀ via. Analogamente,
> a*b
[1] 7 16 27 40 55
> log(b)
[1] 1.945910 2.079442 2.197225 2.302585 2.397895
> d<-rep(10,5)
> a+b+d
[1] 18 20 22 24 26
> a>b
[1] F F F F F
Anche nel caso in cui uno dei termini sia uno scalare, l’operazione viene
eseguita componente per componente. Ad esempio,
> a^2
[1] 1 4 9 16 25
> a*2+b
[1] 9 12 15 18 21
> a*(2+b)
[1] 9 20 33 48 65
> a<=3
[1] T T T F F
Alcune funzioni utili per la manipolazione di vettori sono:
> x<-26:3
> length(x) restituisce il numero di elementi di x
[1] 24
> max(x) restituisce il massimo di x
[1] 26
> min(x) restituisce il minimo di x
7
[1] 3
> sum(x) restituisce la somma degli elementi di x
[1] 348
> prod(x) restituisce il prodotto degli elementi di x
[1] 2.016457e+26
> sort(x) ordina gli elementi di x in ordine crescente
[1] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
> x<-seq(0,20,10)
> x
[1] 0 10 20
> x[1]
[1] 0
> x[3]
[1] 20
> x[1:2]
[1] 0 10
> x[c(1,3)]
[1] 0 20
> x<-seq(1,10,2)
> x
[1] 1 3 5 7 9
> x[c(-1,-4)]
[1] 3 5 9
8
si escludono dal vettore x gli elementi di posizione 1 e 4.
Sono possibili anche estrazioni di elementi tramite operazioni logiche. Ve-
diamo qualche esempio. Siano peso ed altezza due vettori che contengono,
rispettivamente, il peso (kg) e l’altezza (cm) di 5 individui:
> peso<-c(80,70,82,76,90)
> altezza<-c(170,168,176,181,180)
> peso1<-peso[peso>80]
> peso1
[1] 82 90
> altezza1<-altezza[altezza<=170]
> altezza1
[1] 170 168
vengono assegnati al vettore altezza1 gli elementi del vettore altezza che
sono minori od uguali a 170. Con
> peso2<-peso[altezza>170]
> peso2
[1] 82 76 90
> a<-matrix(1:6,nrow=2)
> a
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
9
L’opzione nrow ci dice quante righe deve avere la matrice risultante (il nume-
ro di colonne è ottenuto per differenza). Nell’esempio precedente, abbiamo
creato una matrice a di due righe (e conseguentemente 3 colonne) in cui
abbiamo disposto i numeri da 1 a 6. Senza ulteriori specificazioni, nella di-
sposizione dei valori si procede per colonna. Se si vuole procedere per riga,
è necessario usare l’opzione byrow=TRUE. Ad esempio, con
> b<-matrix(1:6,nrow=2,byrow=TRUE)
> b
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
si ottiene una matrice b di due righe e tre colonne, ma procedendo per riga.
Altri esempi sono:
> x<-3:8
> matrix(x,ncol=2)
[,1] [,2]
[1,] 3 6
[2,] 4 7
[3,] 5 8
> matrix(x,ncol=2,byrow=TRUE)
[,1] [,2]
[1,] 3 4
[2,] 5 6
[3,] 7 8
Nel primo caso, dal vettore x viene creata una matrice di due colonne pro-
cedendo per colonna; nel secondo caso, procedendo per riga.
Si possono creare anche matrici di stringhe di caratteri o logiche. Ad
esempio,
> x<-c("pippo","pluto","topolino","paperino")
> matrix(x,ncol=2)
[,1] [,2]
[1,] "pippo" "topolino"
[2,] "pluto" "paperino"
> matrix(c(3>=2,3<=5,2==2,1<0),nrow=2)
[,1] [,2]
[1,] TRUE TRUE
[2,] TRUE FALSE
Come accade per i vettori, anche le matrici non possono essere di tipo misto,
ad esempio numerico e di caratteri.
Per conoscere le dimensioni di una matrice, si usa la funzione dim:
10
> dim(a)
[1] 2 3
> a<-rbind(peso,altezza)
> a
[,1] [,2] [,3] [,4] [,5]
peso 80 70 82 76 90
altezza 170 168 176 181 180
> b<-cbind(peso,altezza)
> b
peso altezza
[1,] 80 170
[2,] 70 168
[3,] 82 176
[4,] 76 181
[5,] 90 180
> b[2,2]
[1] 168
> b[5,1]
[1] 90
> a[1,]
[1] 80 70 82 76 90
11
> a[,2]
peso altezza
70 168
> b[1:3,2]
[1] 170 168 176
> a[1,c(1,4,5)]
[1] 80 76 90
> b[b[,2]>175,]
peso altezza
[1,] 82 176
[2,] 76 181
[3,] 90 180
> b[b[,1]>80,]
peso altezza
[1,] 82 176
[2,] 90 180
> a<-matrix(0:5,nrow=2)
> b<-matrix(seq(0,10,2),nrow=2)
> a
[,1] [,2] [,3]
[1,] 0 2 4
[2,] 1 3 5
12
> b
[,1] [,2] [,3]
[1,] 0 4 8
[2,] 2 6 10
> a+b
[,1] [,2] [,3]
[1,] 0 6 12
[2,] 3 9 15
> a*b
[,1] [,2] [,3]
[1,] 0 8 32
[2,] 2 18 50
> a==5
[,1] [,2] [,3]
[1,] FALSE FALSE FALSE
[2,] FALSE FALSE TRUE
13
Per calcolare la trasposta di una matrice si usa la funzione t:
> t(d)
[,1] [,2]
[1,] 20 26
[2,] 56 80
14
> indagine[,2]
[1] 170 168 176 181 180
> indagine[3,]
peso altezza fumatore
3 82 176 No
> indagine[indagine[,3]=="Si",]
peso altezza fumatore
1 80 170 Si
2 70 168 Si
5 90 180 Si
L’ultimo comando restituisce le righe relative ai soli fumatori.
Molti dei comandi e delle operazioni che si eseguono su matrici, possono
essere eseguite anche su data frame. Naturalmente, se la funzione o l’opera-
zione richiede un argomento numerico, essa potrà essere applicata solo alle
colonne numeriche del data frame. Ad esempio,
> dim(indagine)
[1] 5 3
> sum(indagine[,2])
[1] 875
15
shelf Numerazione dello scaffale in cui sono state disposte
(1, 2, o 3, contando dal basso)
vitamins Presenza di vitamine e minerali (none=nessuna,
enriched=arricchito, o 100%= fabbisogno giornaliero)
> cereali=read.table("C:/mywork/UScereal.txt",header=TRUE)
> dim(cereali)
[1] 65 9
> cereali[1:3,]
prod mfr calories protein fat fibre sugars
1 100% Bran N 212.1 12.1 3 30.3 18.2
2 All-Bran K 212.1 12.1 3 27.3 15.2
3 All-Bran with Extra Fiber K 100.0 8.0 0 28.0 0.0
shelf vitamins
1 3 enriched
2 3 enriched
3 3 enriched
> attach(cereali)
> protein[1:3]
[1] 12.1 12.1 8.0
> kelloggs=cereali[mfr=="K",]
> write.table(kelloggs,"C:/mywork/Kelloggs.txt", col.names=TRUE,
+ row.names=FALSE, quote=FALSE)
16
Tramite l’opzione col.names=TRUE richiediamo che nel file di testo vengano
riportati i nomi delle colonne; tramite l’opzione row.names=FALSE si specifica
che il file di uscita non deve riportare i nomi delle righe (nel nostro esempio
non presenti); in fine, tramite l’opzione quote=FALSE si precisa che nel file
di uscita le stringhe di caratteri non devono essere racchiuse tra virgolette.
Per maggiori dettagli si veda l’Help di write.table. Si noti che è possibile
andare a capo durante la scrittura di un’istruzione; R inserisce nella nuova
riga il simbolo + solo per indicare la continuazione del comando.
1.10 Esercizi
Esercizio 1
Si costruisca un vettore x di elementi 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5,
5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5 e 10. Per x si calcolino la lunghezza, la
somma degli elementi, il prodotto degli elementi.
Esercizio 2
Per il vettore x dell’Esercizio 1 si calcolino la media e la varianza
mediante l’uso delle funzioni length e sum.
Esercizio 3
Dai vettori
> x<-c(3,5,9,1,2,10,12,24,6),
> y<-c(0.15,0,0.32,0.51,0.18,0.22,0.6,0.98,0.12)
> z<-c(123,415,981,643,1080,89,46,75,910)
> x<-c(20,3,26,14,22,14,5,24,28,21,17,29,24,1,25,26,27,7,11,25,
+ 20,25,9,16,20,7,19,27,30,2)
17
> y
a b
1 2 I
2 3 II
3 4 III
Esercizio 6
Dal data frame cereali si costruisca il data frame general.mills
contenente le informazioni riferite solo alla marca General Mills. Si
calcoli, quindi, media e varianza del contenuto calorico per i prodotti
della General Mills e la percentuale di prodotti della stessa marca con
contenuto vitaminico arricchito.
18
Capitolo 2
Statistica descrittiva
2.1 Introduzione
In questo capitolo vedremo come condurre un’analisi descrittiva dei dati
mediante tabelle di frequenza, indici sintetici e strumenti grafici, usando i
comandi disponibili in R.
> studenti=read.table("C:/mywork/Studenti.txt",header=TRUE)
> dim(studenti)
[1] 65 8
19
> studenti
IND SESSO ANASC SCUOLA MAT STAT ECON DIR
1 Amm. F 1963 ITC 58 30 30 31
2 Eco. M 1964 ITC 50 23 24 26
3 Soc. F 1964 Scien. 51 26 27 30
4 Amm. F 1963 ITC 48 23 24 27
....
63 Soc. F 1968 ITC 60 18 25 25
64 Amm. M 1969 ITC 42 25 19 25
65 Amm. F 1967 ITA 46 20 19 27
La principale funzione per la costruzione di tabelle di frequenza è table.
Vediamone il funzionamento, costruendo la tabella delle frequenze assolute
per la variabile IND (indirizzo di studi).
> attach(studenti)
> table(IND)
IND
Altro Amm. Eco. Soc.
1 27 19 18
> sum(table(IND))
[1] 65
Il risultato di table è un vettore i cui elementi sono le frequenze assolute delle
varie modalità (si noti che ad ogni frequenza viene associato il nome della
modalità corrispondente). Se vogliamo la tabella delle frequenze relative:
> n=length(IND)
> tab.freq.rel.IND=table(IND)/n
> tab.freq.rel.IND
IND
Altro Amm. Eco. Soc.
0.01538462 0.41538462 0.29230769 0.27692308
> sum(tab.freq.rel.IND)
[1] 1
Costruiamo la tabella di frequenza anche per la variabile ANASC (anno di
nascita):
> tab.freq.ANASC=table(ANASC)
> tab.freq.ANASC
ANASC
1949 1957 1960 1962 1963 1964 1965 1966 1967 1968 1969 1970
1 1 1 4 3 6 7 9 9 22 1 1
> tab.freq.rel.ANASC=tab.freq.ANASC/n
20
> tab.freq.rel.ANASC
ANASC
1949 1957 1960 1962 1963 1964
0.01538462 0.01538462 0.01538462 0.06153846 0.04615385 0.09230769
1965 1966 1967 1968 1969 1970
0.10769231 0.13846154 0.13846154 0.33846154 0.01538462 0.01538462
Dalla tabella delle frequenze possiamo ricavare la tabella delle frequenze cu-
mulate tramite la funzione cumsum. Tale funzione crea un vettore di dimen-
sione pari a quello in entrata i cui elementi rappresentano le somme cumulate
parziali.
> tab.freqcum.ANASC=cumsum(tab.freq.ANASC)
> tab.freqcum.ANASC
1949 1957 1960 1962 1963 1964 1965 1966 1967 1968 1969 1970
1 2 3 7 10 16 23 32 41 63 64 65
> tab.freqcum.rel.ANASC=cumsum(tab.freq.rel.ANASC)
> tab.freqcum.rel.ANASC
1949 1957 1960 1962 1963 1964
0.01538462 0.03076923 0.04615385 0.10769231 0.15384615 0.24615385
1965 1966 1967 1968 1969 1970
0.35384615 0.49230769 0.63076923 0.96923077 0.98461538 1.00000000
> media.STAT=sum(STAT)/n
> media.STAT
[1] 24.33846
> STAT.ord=sort(STAT)
> mediana.STAT=STAT.ord[33]
> mediana.STAT
[1] 25
21
> varianza.STAT=sum((STAT-media.STAT)^2)/n
> varianza.STAT
[1] 18.96237
ma è calcolabile anche come differenza tra momento secondo e momento
primo al quadrato, ossia
> varianza2.STAT=sum(STAT^2)/n-media.STAT^2
> varianza2.STAT
[1] 18.96237
Se vogliamo lo scarto quadratico medio, basterà prendere
> sqrt(varianza.STAT)
[1] 4.35458
Per il calcolo dello scarto interquartilico abbiamo bisogno del primo e del
terzo quartile, ossia dei quantili 0.25 e 0.75. A questo fine costruiamo le
frequenze relative cumulate di STAT
> tab.freqcum.rel.STAT=cumsum(table(STAT)/n)
> tab.freqcum.rel.STAT
18 19 20 21 22 23 24
0.1692308 0.2153846 0.2923077 0.3076923 0.3230769 0.3692308 0.4769231
25 26 27 28 29 30 31
0.5846154 0.6769231 0.7384615 0.7846154 0.8000000 0.9230769 1.0000000
da cui vediamo che il primo quartile è 20 e il terzo quartile è 28. Lo scarto
interquartilico è 28-20=8.
Dopo tutto questo lavoro, che è stato utile per ripassare alcune proprietà
degli indici sintetici, vediamo quali sono le vere potenzialità di R per il calcolo
di tali misure.
Le principali funzioni di R per il calcolo di indici di posizione e variabilità
sono
• min calcola il valore minimo del vettore;
• range fornisce i valori del minimo e del massimo, ossia gli estremi del
campo di variazione;
22
• quantile calcola i quantili di qualsiasi ordine;
• summary fornisce una tabella che riassume maggior parte dei valori
sopra esposti.
> min(STAT)
[1] 18
> max(STAT)
[1] 31
> range(STAT)
[1] 18 31
> mean(STAT)
[1] 24.33846
> median(STAT)
[1] 25
> var(STAT)
[1] 19.25865
> varianza.STAT
[1] 18.96237
> sum((STAT-mean(STAT))^2)/(n-1)
[1] 19.25865
> quantile(STAT,0.25)
25%
20
> quantile(STAT,0.75)
75%
28
> quantile(STAT,c(0.25,0.75))
25% 75%
20 28
> quantile(STAT,c(0.05,0.95))
5% 95%
18 31
> summary(STAT)
Min. 1st Qu. Median Mean 3rd Qu. Max.
18.00 20.00 25.00 24.34 28.00 31.00
23
2.4 Grafici
2.4.1 Grafici per variabili qualitative
I principali grafici per variabili qualitative sono:
> tabella.IND=table(IND)
> tabella.IND
IND
Altro Amm. Eco. Soc.
1 27 19 18
> pie(tabella.IND)
> pie(tabella.IND,labels=c("Altro","Amministrativo","Economico",
+ "Sociologico"))
> barplot(tab.freq.rel.IND)
> barplot(tab.freq.rel.IND, names.arg=c("Altro","Amministrativo",
+ "Economico","Sociologico"))
24
> tabella.IND.rel.riord= tabella.IND.rel[c(2:4,1)]
> tabella.IND.rel.riord
IND
Amm. Eco. Soc. Altro
0.41538462 0.29230769 0.27692308 0.01538462
> barplot(tabella.IND.rel, names.arg=c("Amministrativo",
+ "Economico","Sociologico","Altro"))
La funzione barplot può essere usata anche per fare dei confronti. (Ri-
cordate che i confronti tra distribuzioni devono essere fatti in termini di
frequenze relative!). Inventiamo alcune valori che supponiamo rappresentare
la distribuzione dell’indirizzo di studi per gli studenti della facoltà di Scienze
Politiche dell’Università di Padova.
> tabella.IND.PD=c(20,20,10,5)
> tabella.IND.PD.rel=tabella.IND.PD/sum(tabella.IND.PD)
> tabella.congiunta=rbind(tabella.IND.rel.riord,tabella.IND.PD.rel)
> barplot(tabella.congiunta,names.arg=c("Amministrativo",
+ "Economico","Sociologico","Altro"))
> barplot(tabella.congiunta,names.arg=c("Amministrativo",
+ "Economico","Sociologico","Altro"),beside=TRUE)
25
• gli istogrammi, realizzabili con la funzione hist;
26
R non ci permette un controllo totale del numero di classi, come accade
per nclass=2. Si noti come il numero delle classi possa modificare com-
pletamente la forma del grafico. Ad esempio, con sole 3 classi (ottenute da
nclass=2) perdiamo tutti i dettagli della distribuzione, inclusa la bimodalità.
Abbiamo, in altre parole, sintetizzato troppo i nostri dati. Per contro, con
nclass=30 il grafico è troppo irregolare per permettere un’interpretazione
del fenomeno.
Per intervenire, non solo sul numero delle classi, ma anche sulla divisione
in classi, dobbiamo utilizzare l’opzione breaks, dando i punti di interruzione
degli intervalli.
> boxplot(sugars)
> boxplot(calories)
> boxplot(calories,range=0)
27
Sappiamo dal corso di Statistica che i boxplot si prestano a confrontare
distribuzioni di frequenza. Supponiamo di voler confrontare tramite boxplot
la distribuzione del contenuto di zuccheri per le diverse marche di cereali.
> table(mfr)
mfr
G K N P Q R
22 21 3 9 5 5
> zuccheri.G=sugars[mfr=="G"]
> zuccheri.K=sugars[mfr=="K"]
> zuccheri.N=sugars[mfr=="N"]
> zuccheri.P=sugars[mfr=="P"]
> zuccheri.Q=sugars[mfr=="Q"]
> zuccheri.R=sugars[mfr=="R"]
> boxplot(zuccheri.G,zuccheri.K,zuccheri.N,zuccheri.P,zuccheri.Q,
+ zuccheri.R)
> boxplot(zuccheri.G,zuccheri.K,zuccheri.N,zuccheri.P,zuccheri.Q,
+ zuccheri.R, names=c("G.Mills","Kelloggs","Nabisco","Post",
+ "Quaker","Ralston"))
Con l’opzione names è possibile dare un nome a ciascuna scatola. Dal con-
fronto dei boxplot possiamo dedurre che mentre la General Mills, la Kelloggs
e la Nabisco tendono a coprire l’intera gamma di prodotti, da quelli meno
zuccherati a quelli più zuccherati, la Post e la Quaker Oats tendono a fo-
calizzarsi su prodotti ad alto contenuto di zuccheri e la Ralston Purina su
prodotti a basso contenuto di zuccheri.
I boxplot affiancati prodotti attraverso le precedenti istruzioni, possono
essere ottenuti con un unico comando se facciamo ricorso alla funzione split:
> boxplot(split(sugars,mfr))
> split(sugars,mfr)
$G
[1] 13.3 10.7 0.8 12.0 14.0 13.0 13.0 13.3 12.0 13.3 2.0 12.0
[13] 6.0 20.0 16.0 3.0 14.0 3.0 4.0 12.0 3.0 10.7
$K
[1] 15.2 0.0 14.0 2.0 12.0 14.0 3.0 13.0 14.7 8.8 17.9 12.0
[13] 19.4 13.4 10.4 3.0 16.0 12.0 3.0 20.0 3.0
$N
[1] 18.2 0.0 0.0
$P
28
[1] 7.5 14.9 16.0 17.0 5.7 12.0 12.1 8.3 20.9
$Q
[1] 16 11 9 0 12
$R
[1] 9.0 3.0 6.7 1.8 4.5
Tramite split(sugars,mfr) otteniamo una suddivisione delle osservazioni
sul contenuto di zuccheri in base alle modalità assunte da mfr (le diverse
marche). Il risultato può essere dato in input a boxplot per la costruzione
di boxplot affiancati.
vitamins
29
31 enriched
32 enriched
Sono entrambi prodotti della Post, con un numero di calorie piuttosto elevato,
ma con un livello medio del contenuto di zuccheri. Possiamo però notare che
l’unità 32 è caratterizzata da un elevato tasso di grassi, che potrebbe spiegare
l’alto numero di calorie. Tale spiegazione non regge per l’unità 31.
> tabella.freq.rel.ANASC
ANASC
1949 1957 1960 1962 1963 1964
0.01538462 0.01538462 0.01538462 0.06153846 0.04615385 0.09230769
1965 1966 1967 1968 1969 1970
0.10769231 0.13846154 0.13846154 0.33846154 0.01538462 0.01538462
> plot(c(1949,1957,1960,1962:1970),tabella.freq.rel.ANASC,type="h",
+ xlab="anno di nascita", ylab="frequenze relative")
> points(c(1949,1957,1960,1962:1970),tabella.freq.rel.ANASC)
30
2.5 Misure di dipendenza tra due variabili
quantitative
Avendo introdotto i diagrammi di dispersione, sembra ragionevole affrontare
ora il problema di valutare, tramite opportune misure, la dipendenza tra due
variabili quantitative. Come sappiamo dal corso di Statistica, le misure più
usate per la quantificazione della dipendenza tra due variabili quantitative
sono
• la covarianza, ossia la media del prodotto degli scarti delle due variabili
dalle rispettive medie
• la correlazione, pari alla covarianza diviso il prodotto degli scarti qua-
dratici medi delle due variabili
Calcoliamo la covarianza tra le variabili sugars e calories in modo da
associare una misura di dipendenza al grafico di dispersione ottenuto nel
paragrafo 2.4.3.
> cov.zuccheri.calorie=mean((sugars-mean(sugars))*
+ (calories-mean(calories)))
> cov.zuccheri.calorie
[1] 177.4767
Ricordiamo che la covarianza può essere anche calcolata come differenza tra
la media del prodotto e il prodotto delle medie. Seguiamo anche questo
procedimento.
> cov2.zuccheri.calorie=mean(sugars*calories)-mean(sugars)*
+ mean(calories)
> cov2.zuccheri.calorie
[1] 177.4767
Per la correlazione,
> corr.zuccheri.calorie=cov.zuccheri.calorie/
+ sqrt((mean(calories^2)-mean(calories)^2)*
+ (mean(sugars^2)-mean(sugars)^2))
> corr.zuccheri.calorie
[1] 0.4952234
Il valore ottenuto indica la presenza di un buon grado di dipendenza lineare
tra le due variabili.
Come visto per gli indici di posizione e variabilità, anche per covarianza
e correlazione non è necessario il calcolo “manuale”, come fatto nei passi
precedenti, perché è possibile avvalersi delle funzioni di R cov e cor per
ottenere direttamente le due misure.
31
> cov(sugars,calories)
[1] 180.2497
> cov(sugars,calories)*(length(sugars)-1)/length(sugars)
[1] 177.4767
> cor(sugars,calories)
[1] 0.4952234
> cor(sugars[c(-31,-32)],calories[c(-31,-32)])
[1] 0.6651287
Aumenta nettamente.
Calcoliamo ora covarianza e correlazione anche per le due variabili fat e
calories
> cov(fat,calories)
[1] 60.68219
> cor(fat,calories)
[1] 0.5895244
> cor(fat[-c(31)],calories[-c(31)])
[1] 0.8112045
32
2.6 Salvataggio dei grafici
I grafici prodotti in R possono essere stampati, semplicemente selezionando il
grafico e quindi scegliendo l’opzione Print... dal menu di File. In alternativa,
possono essere salvati su disco, selezionando il grafico e quindi scegliendo
l’opzione Save as dal menu di File. A questo punto, vengono offerti vari
formati, la cui scelta dipende dall’uso che si intende fare del grafico. Il
formato jpeg si presta per l’importazione in file Word (cosı̀ come il formato
metafile), mentre il formato pdf è consigliabile per la stampa.
2.7 Esercizi
È stato messo a disposizione degli studenti il file cars.txt. Esso rappresenta
un data set relativo a 93 automobili (righe) per le quali sono state rilevate 9
variabili (colonne) di seguito descritte:
Esercizio 1
Si precisi la natura di ciascuna delle 9 variabili: ad esempio, Type è
una variabile qualitativa. Con l’esclusione della variabile Model, per
tutte le altre variabili qualitative si costruiscano: (a) la tabella delle
frequenze assolute; (b) la tabella delle frequenze relative. Per le va-
riabili quantitative discrete, oltre alle tabelle delle frequenze assolute
e delle frequenze relative, si costruisca anche la tabella delle frequenze
relative cumulate.
33
Esercizio 2
Con l’esclusione della variabile Model, si rappresenti graficamente la di-
stribuzione delle frequenze di ciascuna variabile tramite il diagramma
che si ritiene appropriato, tendendo conto della natura della variabile
stessa. Ad esempio, la variabile Type è qualitativa, pertanto si potrà
ricorrere sia ad un diagramma a torta che ad un diagramma a rettan-
goli separati. In base ai grafici ottenuti, si commentino le principali
caratteristiche delle distribuzioni delle variabili rilevate.
Esercizio 3
Per la variabile Horsepower si costruiscano diversi istogrammi, facendo
variare, rispetto alla scelta di default di R , il numero di classi median-
te l’opzione nclass e le classi stesse mediante l’opzione breaks. Si
commentino i risultati ottenuti.
Esercizio 4
Per ciascuna variabile quantitativa si calcolino: (a) la media, (b) la
mediana, (c) la varianza e lo scarto quadratico medio, (d) i quantili
0.05, 0.25, 0.75 e 0.95, (e) lo scarto interquartilico e (f) il campo di
variazione, tramite le funzioni di R trattate al paragrafo 2.3.
Esercizio 5
Si confrontino le distribuzioni della variabile Horsepower condiziona-
te alle modalità della variabile AirBags attraverso boxplot affiancati.
A questo fine si faccia ricorso alla funzione split. Si commentino i
risultati.
Esercizio 6
Si costruisca il diagramma di dispersione della variabile Horsepower
contro la variabile EngineSize. Si commenti la relazione tra le due
variabili evidenziata dal grafico e si identifichino le unità che paiono
discostarsi dall’andamento generale.
Esercizio 7
Si calcolino covarianza e correlazione tra Horsepower e EngineSize,
usando le funzioni cov e cor, sia includendo tutte le osservazioni sia
escludendo quei punti che sono risultati anomali in base al grafico
ottenuto all’Esercizio 6.
Esercizio 8
Si ripetano le operazioni richieste dagli esercizi 6 e 7 con le variabili
EngineSize e Length.
34
Capitolo 3
Probabilità
• una funzione che inizia per d per il calcolo dalla funzione di densità
(per variabili casuali continue) o di probabilità (per variabili casuali
discrete)
• una funzione che inizia per p per il calcolo della funzione di ripartizione
• una funzione che inizia per r per la simulazione di valori dalla distri-
buzione.
35
cui le funzioni dovranno essere valutate. Le funzioni per il calcolo dei quan-
tili richiedono come primo argomento il vettore prob del’ordine dei quantili,
ossia le probabilità che devono essere lasciate alla sinistra dei quantili. Le
funzioni per la simulazione richiedo come primo argomento il numero num di
punti da simulare. Vediamo il funzionamento di alcune di queste funzioni.
Vogliamo calcolare la funzione di probabilità di una variabile casuale
Bin(n=10,p=0.3) e rappresentarla graficamente tramite un diagramma a ba-
stoncini.
> x=0:10
> prob.binom=dbinom(x,10,0.3)
> cbind(x,prob.binom)
x prob.binom
[1,] 0 0.0282475249
[2,] 1 0.1210608210
[3,] 2 0.2334744405
[4,] 3 0.2668279320
[5,] 4 0.2001209490
[6,] 5 0.1029193452
[7,] 6 0.0367569090
[8,] 7 0.0090016920
[9,] 8 0.0014467005
[10,] 9 0.0001377810
[11,] 10 0.0000059049
> plot(x,prob.binom,type="h")
> points(x,prob.binom)
> pbinom(x,10,0.3)
[1] 0.02824752 0.14930835 0.38278279 0.64961072 0.84973167 0.95265101
[7] 0.98940792 0.99840961 0.99985631 0.99999410 1.00000000
> qbinom(c(0.1,0.9),10,0.3)
[1] 1 5
36
che possiamo verificare essere corretti guardando ai valori della funzione di
ripartizione.
Vediamo alcuni esempi con la variabile casuale normale. Ricostruiamo
per punti e rappresentiamo graficamente la funzione di densità della variabile
casuale N (0, 1).
> x=seq(-5,5,0.1)
> den.norm=dnorm(x,0,1)
> plot(x,den.norm,type="l")
> den.norm2=dnorm(x,0,2)
> den.norm3=dnorm(x,1,1)
> lines(x,den.norm2,col="red")
> lines(x,den.norm3,col="green")
> pnorm(1,0,1)
[1] 0.8413447
> pnorm(1,0,2)
[1] 0.6914625
> pnorm(1,1,1)
[1] 0.5
> x=seq(-3,7,0.1)
> rip.norm=pnorm(x,2,2)
> plot(x,rip.norm,type="l")
37
> qnorm(c(0.05,0.95),0,1)
[1] -1.644854 1.644854 #per la simmetria attorno a 0
> qnorm(c(0.05,0.95),0,2)
[1] -3.289707 3.289707 #per la simmetria attorno a 0
> qnorm(c(0.05,0.95),1,1)
[1] -0.6448536 2.6448536
Come per la distribuzione normale, anche per le variabili casuali χ2 , t ed F
la funzione di ripartizione e i quantili non possono essere calcolati in modo
esplicito, ma questo non è un problema se lavoriamo con R . Vediamo alcuni
esempi di calcolo di quantili per le tre variabili casuali.
> qchisq(c(0.1,0.9),1)
[1] 0.01579077 2.70554345
> qchisq(c(0.1,0.9),10)
[1] 4.865182 15.987179
> qt(c(0.05,0.95),1)
[1] -6.313752 6.313752 #per la simmetria
> qt(c(0.025,0.95),1)
[1] -12.706205 6.313752
> qt(c(0.025,0.95),5)
[1] -2.570582 2.015048
> qt(c(0.025,0.95),10)
[1] -2.228139 1.812461
> qt(c(0.025,0.95),100)
[1] -1.983972 1.660234
> qf(c(0.025,0.975),2,1)
[1] 0.02596976 799.50000000
> qf(c(0.025,0.975),1,2)
[1] 0.001250782 38.506329114 #per l’inversione dei gradi di liberta’
> 1/799.50000000
[1] 0.001250782
> 1/0.02596976
[1] 38.50632
> qf(c(0.025,0.975),5,10)
[1] 0.1510767 4.2360857
In modo analogo, possiamo usare le funzioni pchisq, pt e pf per il calcolo
della funzione di ripartizione delle tre distribuzioni.
3.2 Simulazione
Sinora non abbiamo utilizzato le funzioni che iniziano con r. Come accen-
nato, queste funzioni hanno il ruolo di simulare dei valori dalla distribuzione
38
di probabilità corrispondente. In altre parole, queste funzioni sono in grado
di riprodurre o simulare il comportamento di un fenomeno che segue una
determinata distribuzione di probabilità. Vediamo alcuni esempi.
Simuliamo, nell’ordine, un campione di 10, 100 e 1000 valori da una distri-
buzione N (0, 1). Ricostruiamo quindi la funzione di densità dei valori simula-
ti tramite un istogramma e confrontiamo la forma dell’istogramma ottenuto
con la curva della funzione di densità della variabile casuale N (0, 1).
> campione10=rnorm(10,0,1)
> campione100=rnorm(100,0,1)
> campione1000=rnorm(1000,0,1)
> par(mfrow=c(2,2))
> hist(campione10,freq=FALSE)
> x=seq(-5,5,0.1)
> lines(x,dnorm(x,0,1))
> hist(campione100,freq=FALSE)
> lines(x,dnorm(x,0,1))
> hist(campione1000,freq=FALSE)
> lines(x,dnorm(x,0,1))
39
> mean(rchisq(10,3))
> mean(rchisq(100,3))
> mean(rchisq(1000,3))
> mean(rchisq(10000,3))
Un’immediata conseguenza del teorema del limite centrale è che una variabile
casuale Bin(n, p) “assomiglia”, per n sufficientemente grande, ad una variabi-
le casuale N (np, np(1 − p)). Verifichiamo questo risultato costruendo la fun-
zione di probabilità di una variabile casuale Bin(n, 0.3) per valori crescenti di
n e confrontandola con la densità di una variabile casuale N (n·0.3, n·0.3·0.7).
> par(mfrow=c(2,2))
> x=0:5
> plot(x,dbinom(x,5,0.3),type="h")
> xx=seq(0,5,0.1)
> lines(xx,dnorm(xx,5*0.3,sqrt(5*0.3*0.7)))
> x=0:10
> plot(x,dbinom(x,10,0.3),type="h")
> xx=seq(0,10,0.1)
> lines(xx,dnorm(xx,10*0.3,sqrt(10*0.3*0.7)))
> x=0:20
> plot(x,dbinom(x,20,0.3),type="h")
> xx=seq(0,20,0.1)
> lines(xx,dnorm(xx,20*0.3,sqrt(20*0.3*0.7)))
> x=0:50
> plot(x,dbinom(x,50,0.3),type="h")
> xx=seq(0,50,0.1)
> lines(xx,dnorm(xx,50*0.3,sqrt(50*0.3*0.7)))
40
3.4 Tecniche di campionamento
Due tecniche di base per il campionamento da popolazioni finite sono il cam-
pionamento casuale, con e senza ripetizione. Entrambi gli schemi sono as-
similabili ad n estrazioni da un urna costituita da N palline; in un caso le
estrazioni sono fatte con reinserimento, nell’altro senza reinserimento.
Supponiamo di aver numerato gli elementi della popolazione da 1 a N . I
due schemi di campionamento possono essere realizzati generando n nume-
ri casuali da 1 a N , in un caso, rendendo possibili le ripetizioni, nell’altro
senza ripetizioni, e inserendo nel campione le unità della popolazione la cui
numerazione corrisponde ai valori generati. Per la generazione di numeri ca-
suali interi usiamo la funzione sample. Vediamone il funzionamento con un
esempio. Desideriamo estrarre un campione casuale senza ripetizione di nu-
merosità 20 da una popolazione di 1000 unità che abbiamo preventivamente
numerato da 1 a 1000.
> x=sample(1:1000,size=10)
> x
[1] 769 701 905 991 792 122 941 227 176 413
> sort(x)
[1] 122 176 227 413 701 769 792 905 941 991
In base a questi risultati, dovremmo includere nel campione le unità numerate
con 122, 176, ecc.. Per realizzare un campionamento casuale con ripetizione
è necessario utilizzare l’opzione replace=TRUE di sample:
> x=sample(1:1000,size=10,replace=TRUE)
> x
[1] 707 99 915 207 791 99 410 625 701 146
> sort(x)
[1] 99 99 146 207 410 625 701 707 791 915
In questa particolare estrazione casuale, l’unità 99 entra due volte nel cam-
pione.
Un altro schema di campionamento piuttosto diffuso è il campionamento
sistematico. Supponiamo di voler costruire un campione di dimensione n
da una popolazione di N unità. Possiamo procedere in questo modo. Sia
k la parte intera del rapporto N/n. Si estrae un valore casuale tra 1 e k;
sia r tale valore; allora il campione sistematico è formato considerando le
unità che sono state numerate con r, r + k, r + 2k, . . . , r + (n − 1)k. Il
campionamento sistematico può essere considerato casuale se gli elementi
della popolazione sono stati numerati secondo un ordine casuale. Vediamo
un esempio. Vogliamo costruire un campione sistematico di numerosità 10
da una popolazione di 1000 elementi. Allora, k = 1000/10 = 100. Estraiamo
un numero casuale tra 1 e 100, usando sample
41
> sample(1:100,size=1)
[1] 53
Il campione sistematico sarà quindi costituito dalle unità numerate con 53,
153, 253, . . . 953.
42
hanno media diversa da 0 e varianza diversa da 1, prima di usare la funzione
qqnorm è bene standardizzarle (per renderle di media 0 e varianza unitaria)
sottraendo la media e dividendo per lo scarto quadratico medio:
> campione.normale.stand=(campione.normale-mean(campione.normale))/
+ sqrt(var(campione.normale))
> mean(campione.normale.stand)
> var(campione.normale.stand)
> qqnorm(campione.normale.stand)
> abline(0,1)
> campione.normale=rnorm(1000,1,3)
> campione.normale.stand=(campione.normale-mean(campione.normale))/
+ sqrt(var(campione.normale))
> qqnorm(campione.normale.stand)
> abline(0,1)
> campione.chi2=rchisq(1000,2)
> hist(campione.chi2)
> campione.chi2.stand=(campione.chi2-mean(campione.chi2))/
+ sqrt(var(campione.chi2))
> qqnorm(campione.chi2.stand)
> abline(0,1)
43
in accordo con le caratteristiche a noi note della distribuzione χ2 . Da questo
Q–Q plot non abbiamo dubbi sull’irragionevolezza dell’ipotesi di normalità
per il campione considerato.
Concludiamo con una applicazione a dati reali, considerando la variabile
MAT (voto all’esame di maturità ) del data frame studenti. Tale variabile
è discreta, ma con molte modalità, pertanto l’ipotesi che la sua distribu-
zione possa essere approssimata con la distribuzione normale non è a priori
irragionevole (si pensi a come il teorema del limite centrale ci permette di
approssimare una distribuzione binomiale tramite la distribuzione normale,
purché n sia sufficientemente grande). Vogliamo verificare se la forma della
distribuzione delle osservazioni su MAT è compatibile con le caratteristiche
della variabile casuale normale.
> attach(studenti)
> hist(MAT)
> mean(MAT)
[1] 47.98462
> var(MAT)
[1] 45.32788
> MAT.stand=(MAT-mean(MAT))/sqrt(var(MAT))
> qqnorm(MAT.stand)
> abline(0,1)
Alcune osservazioni sono ripetute e questo spiega i punti che formano dei
tratti orizzontali, ma al di là di questo aspetto legato alla natura discreta
della variabile, complessivamente l’adattamento della distribuzione normale
ai dati pare soddisfacente. Per queste osservazioni è, quindi, ragionevole
assumere che il fenomeno che le ha generate si distribuisca normalmente
(con media diversa da 0 e varianza diversa da 1!).
3.6 Esercizi
Esercizio 1
Si ricostruisca per punti e si rappresenti graficamente la funzione di
densità della variabile casuale χ2 con 3 gradi di libertà. Sullo stesso
grafico, si traccino anche le funzioni di densità, ricostruite per punti,
delle variabili casuali χ25 e χ210 , usando linee di colore diverso. Che
cosa accade al crescere dei gradi di libertà? (Suggerimento: per ben
rappresentare le tre funzioni sullo stesso grafico, usate come vettore di
punti sui cui devono essere valutate le densità x=seq(0,20,0.1).)
Esercizio 2
Si ripetano le operazioni descritte nell’Esercizio 1 per le variabili casuali
44
t con 2, 4 e 10 gradi di libertà, rispettivamente, usando colori diversi
per le linee. Sullo stesso grafico si tracci anche la curva della funzione
di densità della normale standard N (0, 1). Che cosa accade al crescere
dei gradi di libertà? (Suggerimento: per ben rappresentare le 4 funzioni
sullo stesso grafico, usate come vettore di punti sui cui devono essere
valutate le densità x=seq(-5,5,0.1).)
Esercizio 3
Si ricostruisca per punti e si rappresenti graficamente la funzione di
ripartizione della variabile casuale F con gradi di libertà 5, 20.
Esercizio 4
Si calcolino i quantili 0.005, 0.025, 0.1, 0.9 , 0.95, 0.975, 0.99 per le
seguenti distribuzioni: N (0, 1), N (10, 52 ), χ27 , t14 , F3,2 . Coincidono con
quelli ottenuti dalla tavole?
Esercizio 5
Si simulino 4 campioni, rispettivamente, di numerosità 10, 50, 100 e
1000 da una distribuzione χ2 con 3 gradi di libertà. Si Suddivida la
finestra grafica in 4 sottofinestre tramite mfrow. Su ciascuna sottofine-
stra si disegni l’istogramma per ogni campione simulato e si tracci sullo
stesso grafico la curva della densità della variabile casuale χ23 , ricostruita
per punti. Che cosa si può dedurre dal confronto dei 4 grafici?
Esercizio 6
Si progetti un campionamento di numerosità 30 da una popolazione di
800 unità secondo le tecniche del campionamento casuale con e sen-
za ripetizione e del campionamento sistematico, usando la funzione
sample.
Esercizio 7
Si simuli un campione di 1000 osservazioni da una distribuzione t con
4 gradi di libertà. Attraverso la funzione qqnorm si confronti la distri-
buzione del campione con la distribuzione normale. Quali discrepanze
sono osservabili? Si ripeta, quindi, l’operazione con la distribuzione t
con 20 gradi di libertà. Che cosa cambia rispetto al caso con 4 gradi
di libertà?
Esercizio 8
Si consideri il data frame cereali. Per tutte le variabili per le qua-
li l’ipotesi di normalità non sia a priori irragionevole, ossia, per tutte
le variabili continue o discrete, ma con molte modalità, si confronti
la distribuzione delle osservazioni con la distribuzione normale tramite
un Q-Q plot normale. Per ogni Q-Q plot ottenuto, si commentino i
45
risultati, precisando se l’adattamento della normale ai dati è soddisfa-
cente e, in caso di allontanamenti dalla normalità, illustrando il tipo
di discrepanze osservate e tentando una spiegazione “fenomenica” delle
discrepanze stesse.
46
Capitolo 4
47
> sleep
extra group
1 0.7 1
2 -1.6 1
3 -0.2 1
...
19 4.6 2
20 3.4 2
Si vuole stimare la media e la varianza dell’aumento nel numero di ore di
sonno separatamente per i due sonniferi.
> attach(sleep)
> stima.media.sonnifero1=mean(extra[group=="1"])
> stima.media.sonnifero1
[1] 0.75
> stima.media.sonnifero2=mean(extra[group=="2"])
> stima.media.sonnifero2
[1] 2.33
> stima.varianza.sonnifero1=var(extra[group=="1"])
> stima.varianza.sonnifero1
[1] 3.200556
> stima.varianza.sonnifero2=var(extra[group=="2"])
> stima.varianza.sonnifero2
[1] 4.009
In base ai risultati ottenuti parrebbe che il secondo sonnifero sia più efficace
del primo, ma come sappiamo abbiamo bisogno di condurre un test di ipotesi
per poter verificare questa affermazione.
Si consideri il data frame cereali. Nell’ipotesi che il campione di 65 pro-
dotti di cereali sia rappresentativo della popolazione di cereali in commer-
cio, si vuole stimare la percentuale di prodotti in commercio con contenuto
vitaminico pari al fabbisogno giornaliero.
> attach(cereali)
> table(vitamins)
vitamins
100% enriched none
5 57 3
> stima.p=5/65
> stima.p
[1] 0.07692308
> length(vitamins[vitamins=="100%"])/65
[1] 0.07692308
48
4.2 Verifica di ipotesi e stima intervallare
Procederemo per passi, considerando i problemi “classici” di verifica di ipotesi
e stima intervallare.
dove il pedice oss di z sottolinea il fatto che si tratta del valore osservato
della statistica test. Rifiutiamo H0 al livello di significatività assegnato α
• se H1 : µ > µ0 , per zoss > z1−α , dove z1−α è il quantile 1 − α della
normale standard;
49
• se p–value< α rifiutiamo H0 al livello di significatività α;
• se H1 : µ < µ0 , p–value=Φ(zoss );
> dieta=c(6.0, 4.7, 3.8, 5.1, 2.5, 1.4, 2.8, 3.3, 5.5, 1.1,
+ 4.3, 5.3, 3.4, 5.8, 5.7, 4.9, 3.1, 2.5, 5.1, 1.8)
> media.dieta=mean(dieta)
> media.dieta
[1] 3.905 #piuttosto piccola rispetto ai 5 kg dei promotori
> var.dieta=var(dieta)
> var.dieta
[1] 2.386816 #accordo con la varianza di popolazione
> dieta.stand=(dieta-mean(dieta))/sqrt(var(dieta))
> qqnorm(dieta.stand)
> abline(0,1)
50
È presente qualche deviazione, ma non cosı̀ grave da farci ritenere irragio-
nevole l’ipotesi che le osservazioni provengano da una distribuzione normale.
Procediamo allora con la verifica di ipotesi e la stima intervallare per µ, nel
caso di popolazione normale con varianza nota. Iniziamo con l’intervallo di
confidenza:
> estremo.inf.ic=media.dieta-qnorm(0.975)*sqrt(2/20)
> estremo.sup.ic=media.dieta+qnorm(0.975)*sqrt(2/20)
> estremo.inf.ic.2=media.dieta-qnorm(0.95)*sqrt(2/20)
> estremo.sup.ic.2=media.dieta+qnorm(0.95)*sqrt(2/20)
> estremo.inf.ic
[1] 3.285205
> estremo.sup.ic
[1] 4.524795
> estremo.inf.ic.2
[1] 3.384852
> estremo.sup.ic.2
[1] 4.425148
Abbiamo usato due livelli di confidenza: per 1 − α = 0.95, abbiamo ottenuto
l’intervallo (3.29 kg, 4.52 kg); per 1 − α = 0.9, abbiamo ottenuto l’intervallo
(3.38 kg, 4.43 kg).
Per la relazione esistente tra intervalli di confidenza e verifica di ipotesi
con alternativa bilaterale, in base a questi risultati siamo subito in grado di
concludere che H0 : µ = 5 kg viene rifiutata sia al livello α = 0, 1 che al livello
α = 0, 05, a favore dell’ipotesi alternativa bilaterale H1 : µ 6= 5 kg. Tuttavia,
per il caso in esame, verosimilmente l’interesse è per un’ipotesi alternativa
unilaterale del tipo H1 : µ < 5 kg; in aggiunta, vogliamo seguire l’approccio
basato sul valore del p–value.
> statistica.test=(media.dieta-5)/sqrt(2/20)
> statistica.test
[1] -3.462694
> p.value=pnorm(statistica.test)
> p.value
[1] 0.0002673981
Il valore ottenuto è molto basso. L’indicazione dataci dal p–value è che l’i-
potesi nulla è inverosimile alla luce dei dati osservati, i quali invece danno
sostegno all’ipotesi alternativa H1 : µ < 5. Si noti che, seguendo un ap-
proccio “classico” alla verifica di ipotesi, rifiuteremmo H0 a favore di H1 per
qualunque valore ragionevole del livello di significatività α (α ∈ (0.01, 0.1)).
A titolo esemplificativo, calcoliamo il p–value anche per le ipotesi alter-
native H1 : µ > 5 e H1 : µ 6= 5:
51
> p.value=1-pnorm(statistica.test)
> p.value
[1] 0.9997326 #molto alto, evidenza empirica a favore di Ho
> p.value=2*(1-pnorm(abs(statistica.test)))
> p.value
[1] 0.0005347961 #molto basso, evidenza empirica a sfavore di Ho
Si noti come la “plausibilità” di H0 dipenda fortemente dall’alternativa con-
templata: nel caso H1 : µ > 5, l’ipotesi alternativa è ancor più inverosimile
di H0 , da cui il valore alto del p–value (si accetterebbe H0 e si rifiutereb-
be H1 per qualunque valore ragionevole del livello di significatività α), nel
caso H1 : µ 6= 5, che comprende anche l’intervallo µ < 5 kg, l’ipotesi H0
ritorna ad essere inverosimile tanto da essere rifiutata a qualunque livello di
significatività α ragionevole.
52
data: dieta
t = -3.1697, df = 19, p-value = 0.002523
alternative hypothesis: true mean is less than 5
95 percent confidence interval:
-Inf 4.502342
sample estimates:
mean of x
3.905
• df: sono i gradi di libertà del test (i gradi di libertà della distribuzione
t di riferimento).
53
> t.test(dieta, alternative="two.sided", mu=5, conf.level=0.99)
data: dieta
t = -3.1697, df = 19, p-value = 0.005045
alternative hypothesis: true mean is not equal to 5
99 percent confidence interval:
2.916669 4.893331
sample estimates:
mean of x
3.905
data: dieta
t = -3.1697, df = 19, p-value = 0.9975
alternative hypothesis: true mean is greater than 5
99 percent confidence interval:
3.027717 Inf
sample estimates:
mean of x
3.905
54
Considereremo nel seguito solo il caso in cui le due varianze di popolazione
σ12 e σ22 siano ignote e ipotizziamo, in aggiunta, che siano tra loro uguali
σ12 = σ22 = σ 2 . Con tali specificazioni, sia gli intervalli di confidenza che
la verifica di ipotesi per il confronto delle medie nelle due popolazioni sono
basate sulla distribuzione t. Per questo motivo, la verifica di ipotesi viene
chiamata test t a due campioni (cfr. test t ad un campione del paragrafo
4.2.1).
L’intervallo di confidenza di livello 1 − α per µ1 − µ2 è
s !
1 1
(x̄ − ȳ) ± tn1 +n2 −2;1−α/2 Sp2 +
n1 n2
dove
• x̄, ȳ sono le medie campionarie di x1 , x2 , . . . , xn1 e y1 , y2 , . . . , yn2 , rispet-
tivamente;
Il p–value è definito in modo analogo al caso del test su una singola media con
varianza nota: basterà sostituire alla funzione di ripartizione della normale
standard la funzione di ripartizione della distribuzione t con n1 + n2 − 2 gradi
di libertà e a zoss , toss .
La stessa funzione t.test usata per l’inferenza su una singola media,
può essere usata per il confronto tra le medie di due popolazioni normali.
Vediamone il funzionamento, lavorando con il data frame sleep.
Abbiamo osservato nel paragrafo 4.1 che il secondo sonnifero parrebbe
condurre ad un aumento medio del numero delle ore di sonno superiore ri-
spetto al primo sonnifero. Verifichiamo in modo formale questa affermazione.
Tuttavia, prima di procedere con intervalli di confidenza e test, è bene valu-
tare se le ipotesi alla base degli strumenti che utilizzeremo sono ragionevoli
55
per i campioni osservati. Si tratta, allora, di stabilire se le osservazioni su
ciascuna popolazione seguono una distribuzione normale e se l’assunto di
uguale varianza è plausibile.
> data(sleep)
> attach(sleep)
> boxplot(split(extra,group))
> sonnifero1.stand=(extra[group=="1"]-stima.media.sonnifero1)/
+ sqrt(stima.varianza.sonnifero1)
> qqnorm(sonnifero1.stand)
> abline(0,1)
> sonnifero2.stand=(extra[group=="2"]-stima.media.sonnifero2)/
+ sqrt(stima.varianza.sonnifero2)
> qqnorm(sonnifero2.stand)
> abline(0,1)
> stima.varianza.sonnifero1
[1] 3.200556
> stima.varianza.sonnifero2
[1] 4.009
> t.test(extra[group=="1"],extra[group=="2"],alternative="two.sided",
+ conf.level=0.99,var.equal=TRUE)
56
99 percent confidence interval:
-4.024058 0.864058
sample estimates:
mean of x mean of y
0.75 2.33
La funzione t.test, quando impiegata per il confronto tra due medie, ri-
chiede come argomenti principali i vettori che contengono le osservazioni
campionarie sulle due popolazioni: nel caso in esame, extra[group=="1"] e
extra[group=="2"]. Le opzioni alternative e conf.level hanno lo stes-
so ruolo visto per il test t ad un campione. È necessario utilizzare l’opzione
var.equal=TRUE, con la quale si precisa che il test deve essere condotto sotto
l’ipotesi di uguaglianza tra le due varianze di popolazione, in quanto R è in
grado di condurre il test anche per varianze differenti (è la scelta di default),
ma questo test non verrà da noi trattato. L’output è simile a quello ottenuto
con il test t ad un campione. In particolare,
• t = -1.8608 è il valore osservato della statistica test.
57
sample estimates:
mean of x mean of y
0.75 2.33
Il p–value del test è diminuito: ora H0 verrebbe rifiutata, a favore dell’ipotesi
alternativa unilaterale, anche per α = 0.05 (e per valori più alti di α), ma
continueremmo ad accettarla per α = 0.03 (e a livelli più bassi). Seppure
l’informazione campionaria sia più a sfavore di H0 rispetto al caso prece-
dente, l’evidenza non è cosı̀ netta. Questo potrebbe sembrare un risultato
sorprendente guardando alla grossa differenza tra le due medie campionarie,
ma è opportuno ricordare che il test di ipotesi tiene conto della variabilità
campionaria, che è in questo caso piuttosto elevata relativamente ai valori
delle medie.
Avendo specificato un’ipotesi alternativa unilaterale, il 99 percent confidence
interval è in realtà un estremo superiore e non l’intervallo di confidenza a
noi noto.
58
dove x̄ è la media delle osservazioni di tutti i K campioni, nella somma dei
quadrati between e nella somma dei quadrati within:
con
K
ni (x̄i − x̄)2
X
SSB =
i=1
SSB/(K − 1)
Foss =
SSW/( K
i=1 ni − K)
P
p − value = Pr(FK−1,PK ni −K
> Foss )
i=1
59
> resistenza=c(2.34, 2.46, 2.83, 2.04, 2.69, 2.64, 3.00, 3.19, 3.83,
+ 2.61, 2.07, 2.80, 2.58, 2.98, 2.30, 1.32, 1.62, 1.92, 0.88, 1.50,
+ 1.30, 0.41, 0.83, 0.58, 0.32, 1.62)
> Marca=c(rep("A",5),rep("B", 4), rep("C", 6), rep("D", 6), rep("E",5))
> resistenza
[1] 2.34 2.46 2.83 2.04 2.69 2.64 3.00 3.19 3.83 2.61 2.07 2.80 2.58
[14] 2.98 2.30 1.32 1.62 1.92 0.88 1.50 1.30 0.41 0.83 0.58 0.32 1.62
> Marca
[1] "A" "A" "A" "A" "A" "B" "B" "B" "B" "C" "C" "C" "C" "C" "C" "D"
[17] "D" "D" "D" "D" "D" "E" "E" "E" "E" "E"
> length(resistenza)
[1] 26
> length(Marca)
[1] 26
> Marca.fat=as.factor(Marca)
> Marca.fat
[1] A A A A A B B B B C C C C C C D D D D D D E E E E E
Levels: A B C D E
60
> boxplot(split(resistenza,Marca.fat))
> qqnorm((resistenza[Marca=="A"]-mean(resistenza[Marca=="A"]))/
+ sqrt(var(resistenza[Marca=="A"])))
> abline(0,1)
> qqnorm((resistenza[Marca=="B"]-mean(resistenza[Marca=="B"]))/
+ sqrt(var(resistenza[Marca=="B"])))
> abline(0,1)
> qqnorm((resistenza[Marca=="C"]-mean(resistenza[Marca=="C"]))/
+ sqrt(var(resistenza[Marca=="C"])))
> abline(0,1)
> qqnorm((resistenza[Marca=="D"]-mean(resistenza[Marca=="D"]))/
+ sqrt(var(resistenza[Marca=="D"])))
> abline(0,1)
> qqnorm((resistenza[Marca=="E"]-mean(resistenza[Marca=="E"]))/
+ sqrt(var(resistenza[Marca=="E"])))
> abline(0,1)
> var(resistenza[Marca=="A"])
[1] 0.09497
> var(resistenza[Marca=="B"])
[1] 0.2485667
> var(resistenza[Marca=="C"])
[1] 0.1089067
> var(resistenza[Marca=="D"])
[1] 0.1224667
> var(resistenza[Marca=="E"])
[1] 0.27317
> aov.marche=aov(resistenza~Marca.fat)
> summary(aov.marche)
Df Sum Sq Mean Sq F value Pr(>F)
Marca.fat 4 18.1681 4.5420 28.261 3.475e-08 ***
Residuals 21 3.3751 0.1607
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
61
ai gruppi. I due vettori devono essere separati dal simbolo ~. Nell’esem-
pio trattato, il risultato di aov è stato assegnato all’oggetto aov.marche.
Una sintesi del contenuto di aov.marche può essere ottenuta tramite la fun-
zione summary già incontrata nel secondo capitolo (tale funzione opera in
modi diversi a secondo del tipo di input). In particolare, la sintesi prodotta
comprende:
62
> varieta
[1] "1" "1" "1" "1" "2" "2" "2" "2" "3" "3" "3" "3" "4" "4" "4" "4"
> fw=data.frame(raccolto,varieta)
> attach(fw)
> varieta
[1] "1" "1" "1" "1" "2" "2" "2" "2" "3" "3" "3" "3" "4" "4" "4" "4"
> rm(varieta)
> varieta
[1] 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4
Levels: 1 2 3 4
> rm(raccolto)
> raccolto
[1] 934 1041 1028 935 880 963 924 946 987 951 976 840 992
[14] 1143 1140 1191
Si noti come i vettori creati “prevalgano” sul contenuto del data frame sino
alla loro eliminazione. Si lascia allo studente la verifica empirica delle ipotesi
alla base dell’analisi della varianza e il confronto tra le 4 distribuzioni tramite
boxplot (attenzione alla scarsità di dati!).
> fw.aov=aov(raccolto~varieta)
> summary(fw.aov)
Df Sum Sq Mean Sq F value Pr(>F)
varieta 3 89931 29977 7.2124 0.005034 **
Residuals 12 49876 4156
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
63
I dati sono in genere presentati tramite una tabella, detta tabella a doppia
entrata, di dimensione (r × s), in cui la quantità nella i-esima riga e j-esima
colonna è nij .
Per verificare l’ipotesi nulla H0 di indipendenza stocastica delle due varia-
bili in alternativa a H1 , che invece ipotizza la dipendenza delle due variabili,
si può usare l’indice χ2 , dato da
r X
s
(nij − n∗ij )2
χ2 =
X
,
i=1 j=1 n∗ij
64
Pearson’s Chi-squared test
data: mat
X-squared = 134.6854, df = 4, p-value < 2.2e-16
> assicurazione=read.table("c:/mywork/assicurazione.txt",
+ header=TRUE)
> dim(assicurazione)
[1] 1235 2
> assicurazione
Eta Incidente
1 30-35 Si
2 25-29 Si
3 25-29 Si
...
1234 >35 No
1235 25-29 No
> attach(assicurazione)
> table(Eta)
Eta
<25 >35 25-29 30-35
113 503 238 381
> table(Incidente)
Incidente
No Si
1110 125
65
Poiché i dati sono in forma grezza, la funzione table, introdotta nel capitolo
2 per la costruzione di una tabella di frequenza univariata, viene ora usata per
ottenere la tabella a doppia entrata che verrà data come input a chisq.test:
> table(Eta,Incidente)
Incidente
Eta No Si
<25 80 33
>35 477 26
25-29 210 28
30-35 343 38
> chisq.test(table(Eta,Incidente),correct=FALSE)
4.3 Esercizi
Esercizio 1
Si consideri il data frame studenti. Assumendo che il campione di
65 studenti sia rappresentativo dell’intera popolazione di studenti della
Facoltà di Scienze Politiche, si verifichi l’ipotesi nulla che il voto medio
alla maturità degli studenti di Scienze Politiche sia pari a 50, conside-
rando tutte e 3 le possibili ipotesi alternative. Si commentino i risultati
ottenuti. Si costruisca, inoltre, l’intervallo di confidenza di livello 99%
per lo stesso voto medio.
Esercizio 2
Si acceda al data frame cars. Considerando il campione di 93 modelli
rappresentativo della popolazione di modelli di automobili in commer-
cio, si verifichi l’ipotesi nulla che la lunghezza media dei modelli di
automobili in commercio sia pari a 180 pollici, contro tutte e 3 le pos-
sibili ipotesi alternative. Si commentino i risultati ottenuti. Si costrui-
sca, inoltre, un intervallo di confidenza di livello 95% per la lunghezza
media.
66
Esercizio 3
Si consideri il data frame assicurazione introdotto al paragrafo 4.2.4.
Senza tener conto dell’età e utilizzando noti risultati, si costruisca un
intervallo di confidenza di livello 95% per la percentuale di assicurati
che causano almeno un incidente in un anno.
Esercizio 4
Si considerino i dati sulle marche di impermeabili del paragrafo 4.2.3. È
possibile dire che le marche A, B, C sono più resistenti, in media, delle
marche D,E? A questo fine si creino due vettori per le osservazioni sui
due gruppi di marche. Si costruisca, inoltre, un intervallo di confidenza
di livello 90% per la differenza tra le due medie.
Esercizio 5
I seguenti dati riguardano i tempi di caricamento (in secondi) di due
diverse pagine web per una connessione via modem. Il numero di
osservazioni disponibili per le due pagine sono, rispettivamente, 20 e
25.
Esercizio 6
Si consideri il data frame studenti. Escludendo dall’analisi l’indirizzo
di studi Altro, esiste una differenza significativa tra i voti medi alla
maturità degli studenti che scelgono i restanti indirizzi di studi?
Esercizio 7
In R è incluso il data frame InsectSprays che riguarda il numero di
insetti osservati in unità agricole sperimentali trattate con 6 diversi tipi
di insetticida. Le due colonne del data frame riportano rispettivamente
67
count: numero di insetti
spray: tipo di insetticida (tra A,B,C,D,E e F)
Esercizio 8
È stato messo a disposizione degli studenti il file gelati.txt. Esso
riguarda la preferenza di gusto di gelato di un campione di 40 individui,
classificati per sesso. Le colonne del file sono:
Esercizio 9
Un’indagine su un campione di 100 imprese ha prodotto i seguenti
risultati relativi alla redditività e alla quota di mercato:
Quota di mercato
Redditività <15% 15–30% >30%
Bassa 18 7 8
Media 13 11 8
Alta 8 12 15
68
Capitolo 5
Statistica Inferenziale: il
modello di regressione lineare
5.1 Introduzione
5.1.1 Definizione di un modello di regressione
Un modello di regressione lineare può essere descritto, in generale, nel modo
che segue. Si considerano una variabile risposta Y ed una o più variabili
esplicative X1 , . . . , Xm . La variabile Y è rappresentabile tramite la relazione
Y = β0 + β1 X1 + . . . + βm Xm + ε, (5.1)
in cui β0 ha il ruolo di intercetta (lo si può pensare come ad un coefficiente
associato ad una variabile esplicativa identicamente uguale a 1), β1 , . . . , βm
sono i parametri che individuano la relazione tra Y e le variabili esplicative
ed ε è la variabile dell’errore casuale, che rappresenta la parte di variabilità
di Y non riducibile alla dipendenza da X1 , . . . , Xm .
Avendo a disposizione un insieme di n osservazioni, ciascuna delle qua-
li è prodotta dal modello (5.1), obiettivo è fare inferenza sui parametri
β0 , . . . , βm . Utilizzando la notazione matriciale, si può scrivere
y = Xβ + ε,
dove y = (y1 , . . . , yn )T è il vettore contenente le n osservazioni sulla variabile
risposta, X = [xij ] è la matrice di regressione (o delle condizioni sperimentali)
di dimensione n × (m + 1) contenente i valori delle variabili esplicative (gli
elementi della prima colonna di X sono pari a 1), ε = (ε1 , . . . , εn )T è il vettore
contenente le n componenti della variabile di errore e β = (β0 , . . . , βm )T è il
vettore dei parametri di regressione. Si assume che
εi ∼ N (0, σ 2 ), i = 1, . . . , n, indipendenti.
69
5.1.2 Stima e verifica di ipotesi per un modello di re-
gressione
Lo stimatore di β con il metodo dei minimi quadrati è
β̂ = (X T X)−1 X T y = CX T y,
β̂ ∼ N (β, σ 2 C),
70
di significatività α se Foss > F1−α;m,n−m−1 , ossia Foss è maggiore del quantile
1 − α della distribuzione F con i gradi di libertà sopra specificati. Il p–value
del test è Pr(Fm,n−m−1 > Foss ).
Per verificare l’ipotesi nulla di significatività di un singolo parametro,
ossia H0 : βj = 0 (j = 1, . . . , m) può essere utilizzata la statistica test
β̂j
t= q (5.4)
cjj S 2
1. grafico dei residui, ri , rispetto ai valori stimati dal modello, ŷi . Tale
grafico è utile per verificare se le ipotesi sui termini di errore εi (varianza
costante e indipendenza) sono corrette.
2. grafico dei residui ri rispetto alle variabili esplicative presenti nel mo-
dello. Tale grafico è utile per individuare scorrette specificazioni della
dipendenza dalle variabili esplicative (come, ad esempio, dipendenze
non lineari);
71
5.2 Inferenza su un modello di regressione
lineare in R
La funzione di R per la stima di un modello di regressione lineare multipla
è lm. La sua sintassi generale è
lm(formula)
72
> occupazione=read.table("c:occupazione.txt",header=TRUE)
> attach(occupazione)
> occupazione
Year Employed RealGNP
1 1947 60.323 282.276
2 1948 61.122 293.137
3 1949 60.171 292.578
4 1950 61.187 317.988
5 1951 63.221 341.970
6 1952 63.639 353.720
7 1953 64.989 369.076
8 1954 63.761 363.112
9 1955 66.019 392.756
10 1956 67.857 400.746
11 1957 68.169 408.458
12 1958 66.513 401.215
13 1959 68.655 428.689
14 1960 69.564 440.106
15 1961 69.331 447.859
16 1962 70.551 474.674
> summary(RealGNP)
Min. 1st Qu. Median Mean 3rd Qu. Max.
282.3 336.0 380.9 375.5 413.5 474.7
> summary(Employed)
Min. 1st Qu. Median Mean 3rd Qu. Max.
60.17 62.71 65.50 65.32 68.29 70.55
> boxplot(RealGNP)
> boxplot(Employed)
> plot(RealGNP,Employed)
> cor(RealGNP,Employed)
[1] 0.986509
73
In base ai risultati ottenuti, un modello di regressione lineare semplice della
forma
Employed = β0 + β1 RealGNP + ε,
sembra adeguato a rappresentare la dipendenza di Employed da RealGNP.
Procediamo, allora, con la stima della retta di regressione.
> reg.occupazione=lm(Employed~RealGNP)
> summary(reg.occupazione)
Call:
lm(formula = Employed ~ RealGNP)
Residuals:
Min 1Q Median 3Q Max
-0.8272 -0.3340 -0.1798 0.4612 1.0587
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 43.264226 0.989313 43.73 2.25e-16 ***
RealGNP 0.058726 0.002605 22.55 2.10e-12 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
74
• F-statistic: è il valore osservato della statistica test (5.3) con i gradi
di libertà della distribuzione F di riferimento e il p–value associato al
test.
Employed
d = 43.264226 + 0.058726 × RealGNP
> (cor(RealGNP,Employed))^2
[1] 0.9732
Nel caso di una regressione lineare semplice la statistica test (5.3) è il quadra-
to della statistica test (5.4) riferita al coefficiente di regressione β1 (22.552 =
508.5 e i due p–value sono uguali). Pertanto i due test portano alle mede-
sime conclusioni riguardo all’effetto della variabile esplicativa sulla variabile
dipendente.
Procediamo ora a valutare l’adeguatezza del modello di regressione per i
dati in esame attraverso l’analisi dei residui, iniziando con il diagramma di
dispersione dei residui rispetto ai valori stimati:
75
È opportuno precisare che nella regressione lineare semplice, il diagramma di
dispersione dei residui rispetto alla variabile esplicativa non aggiunge molto
rispetto al diagramma di dispersione dei residui rispetto ai valori stimati,
essendo questi ultimi una semlice trasformazione lineare della variabile espli-
cativa. Tuttavia, acquistiamo da subito l’abitudine di costruire questo tipo di
grafico che nella regressione multipla, trattata nel paragrafo 5.4, è fondamen-
tale. Entrambi i grafici non presentano sistematicità, per cui pare ragionevole
assumere una dipendenza lineare di Employed da RealGNP. Completiamo l’a-
nalisi dei residui con un Q-Q plot normale. A questo riguardo, ricordiamo
che per costruzione i residui ri hanno media nulla
> mean(reg.occupazione$residuals)
[1] -3.903128e-18
ma non hanno, in generale, varianza unitaria
> var(reg.occupazione$residuals)
[1] 0.3305502
pertanto, nel costruire il Q-Q plot normale, standardizziamo i residui divi-
dendo per il loro scarto quadratico medio:
> qqnorm(reg.occupazione$residuals/sqrt(var(reg.occupazione$residuals)))
> abline(0,1)
Il Q-Q plot mostra qualche deviazione dalla retta di riferimento, tuttavia
data la bassa numerosità delle osservazioni è difficile stabilire se queste de-
viazioni sono l’effetto di una reale non normalità dei residui o se sono dovute
a variabilità nei dati. In base ai risultati ottenuti possiamo considerare soddi-
sfacente l’adattamento del modello di regressione ai dati. A completamento,
tracciamo sul diagramma di dispersione di Employed rispetto a RealGNP la
retta di regressione stimata.
> plot(RealGNP,Employed)
> reg.occupazione$coef
(Intercept) RealGNP
43.26422581 0.05872557
Il comando reg.occupazione$coef fornisce le stime dei due coefficienti di
regressione. Pertanto, con
> abline(reg.occupazione$coef)
aggiungiamo la retta di regressione stimata al grafico di dispersione preesi-
stente.
Utilizziamo la retta stimata per prevedere il numero di occupati in funzio-
ne di futuri valori del PIL. A questo fine impieghiamo la funzione predict:
76
> predict(reg.occupazione, data.frame(RealGNP=500),
+ interval="prediction",level=0.95)
fit lwr upr
[1,] 72.62701 71.13889 74.11514
> prev.occupazione=predict(reg.occupazione,
+ data.frame(RealGNP=seq(475,500,5)), interval="prediction",level=0.95)
> prev.occupazione
fit lwr upr
1 71.15887 69.73066 72.58709
2 71.45250 70.01319 72.89182
3 71.74613 70.29526 73.19699
4 72.03976 70.57690 73.50261
5 72.33338 70.85810 73.80867
6 72.62701 71.13889 74.11514
> min(RealGNP)
[1] 282.276
> min(Employed)
[1] 60.171
> plot(RealGNP,Employed,xlim=c(282,500),ylim=c(60,74.2))
77
> points(seq(475,500,5), prev.occupazione[,1],pch=2)
> lines(seq(475,500,5), prev.occupazione[,2])
> lines(seq(475,500,5), prev.occupazione[,3])
> abline(reg.occupazione$coef)
Con l’opzione xlim= di plot si specifica il campo di variazione delle ascisse;
analogamente ylim= specifica il campo di variazione delle ordinate. Entram-
be devono essere seguite da un vettore che contiene, nell’ordine, il valore
minimo e il valore massimo del campo di variazione. L’opzione pch=2 con-
sente di rappresentare i punti nel diagramma con un simbolo diverso da quello
di default. Numeri diversi corrispondono a simboli diversi; il simbolo di de-
fault (il punto) è ottenibile con pch=1. Per maggiori dettagli si veda l’Help
di R alla voce par.
Nel condurre previsioni per dati futuri, è importante ricordare che è, in
generale, pericoloso cercare di prevedere valori della variabile dipendente cor-
rispondenti a valori delle esplicative molto distanti dal campo di osservazione.
78
> attach(cucitrici)
> summary(numero)
Min. 1st Qu. Median Mean 3rd Qu. Max.
13.00 15.00 17.00 17.75 18.25 32.00
> summary(punteggio)
Min. 1st Qu. Median Mean 3rd Qu. Max.
3.700 6.800 7.150 6.883 7.350 7.900
> boxplot(numero)
> boxplot(punteggio)
> plot(numero,punteggio)
> identify(numero,punteggio,n=1)
[1] 8
> cor(numero,punteggio)
[1] -0.9013145
> plot(numero[-8],punteggio[-8])
> cor(numero[-8],punteggio[-8])
[1] -0.3116176
punteggio = β0 + β1 numero + ε
79
> reg.cucitrici1=lm(punteggio~numero)
> summary(reg.cucitrici1)
Call:
lm(formula = punteggio ~ numero)
Residuals:
Min 1Q Median 3Q Max
-0.62914 -0.37320 -0.03143 0.46552 0.76629
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 10.40626 0.55366 18.80 3.94e-09 ***
numero -0.19847 0.03016 -6.58 6.23e-05 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
80
Dal grafico della retta di regressione stimata sul diagramma di dispersione di
numero e punteggio si nota come il modello di regressione cerchi di cogliere il
punto anomalo. Ripetiamo le stesse operazioni, eliminando l’ottava cucitrice.
> punteggio2=punteggio[-8]
> numero2=numero[-8]
> reg.cucitrici2=lm(punteggio2~numero2)
> summary(reg.cucitrici2)
Call:
lm(formula = punteggio2 ~ numero2)
Residuals:
Min 1Q Median 3Q Max
-0.57545 -0.22545 -0.09018 0.23013 0.63571
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 8.20848 1.05994 7.744 2.87e-05 ***
numero2 -0.06295 0.06398 -0.984 0.351
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Tolta l’ottava cucitrice, l’effetto di numero non risulta più significativo. Inol-
tre, l’R2 ha subito una forte riduzione.
> plot(reg.cucitrici2$fitted,reg.cucitrici2$residuals)
> plot(numero2,reg.cucitrici2$residuals)
> qqnorm(reg.cucitrici2$residuals/sqrt(var(reg.cucitrici2$residuals)))
> abline(0,1)
> plot(numero,punteggio)
> abline(reg.cucitrici1$coef)
> abline(reg.cucitrici2$coef)
81
da valori inusuali sia per la variabile esplicativa che per la variabile dipen-
dente. Esso determina uno spostamento del modello di regressione verso il
punto stesso, tanto che in molti casi (come nel presente) può non presentare
un residuo particolarmente elevato.
La scelta di quale insieme di risultati utilizzare (reg.cucitrici1 o reg.cucitrici2?)
è spesso problematica e condizionata alla disponibilità di informazioni ag-
giuntive. Ad esempio, se sospettiamo che l’osservazione influente sia il risul-
tato di un errore di misurazione o di circostanze straordinarie, sarebbe più
opportuno fare affidamento sui risultati ottenuti escludendo il punto stesso.
Se, per contro, riteniamo il punto un’osservazione genuina prodotta sotto
condizioni normali, sarebbe pericoloso non tenerne conto.
Per misurare la discrepanza tra i due modelli, prevediamo il valore di
punteggio per il numero di capi dell’ottava cucitrice, sulla base dei risultati
ottenuti senza il punto influente:
> numero[8]
[1] 32
> predict(reg.cucitrici2,data.frame(numero2=32),
+ interval="prediction", level=0.95)
fit lwr upr
[1,] 6.194196 3.746142 8.642251
> punteggio[8]
[1] 3.7
> miglia.aeree=read.table("c:airmiles.txt",header=TRUE)
> miglia.aeree
miglia anno
1 412 1937
2 480 1938
...
18 16769 1954
19 19819 1955
> attach(miglia.aeree)
82
> summary(miglia)
Min. 1st Qu. Median Mean 3rd Qu. Max.
412 1402 5948 6307 9285 19820
> boxplot(miglia)
> plot(anno,miglia)
Il diagramma di dispersione mette in rilievo una evidente deviazione dall’i-
potesi di linearità. Tuttavia, stimare il modello lineare
miglia = β0 + β1 anno + ε
Call:
lm(formula = miglia ~ anno)
Residuals:
Min 1Q Median 3Q Max
-2556.1 -1808.2 -359.4 1414.1 4506.5
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -1.941e+06 1.731e+05 -11.21 2.82e-09 ***
anno 1.001e+03 8.894e+01 11.25 2.68e-09 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
83
contro i valori stimati e l’anno presentano un andamento sistematico che è
sintomo di una violazione delle ipotesi alla base del modello di regressione e
della incapacità del modello stesso di cogliere a pieno le variazioni di miglia
in funzione di anno. In particolare, il modello stimato non coglie la curvatura
nelle osservazioni. Anche il Q-Q plot normale mostra delle deviazioni sulla
coda sinistra.
Ritorniamo al diagramma di dispersione delle due variabili.
> par(mfrow=c(1,2))
> plot(anno,miglia)
> plot(anno,log(miglia))
> log.miglia=log(miglia)
> reg.miglia2=lm(log.miglia~anno)
> summary(reg.miglia2)
Call:
lm(formula = log.miglia ~ anno)
Residuals:
Min 1Q Median 3Q Max
-0.26002 -0.12180 -0.04432 0.09232 0.52197
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -4.139e+02 1.635e+01 -25.32 6.17e-15 ***
anno 2.169e-01 8.401e-03 25.82 4.46e-15 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
84
Si osservi come i risultati inferenziali siano complessivamente migliorati: sia
la significatività di anno che l’R2 sono aumentati. Tuttavia, questi valori non
sono sufficienti a garantire la bontà di adattamento ai dati del nuovo modello
di regressione. Procediamo, pertanto, all’analisi dei residui.
> par(mfrow=c(1,2))
> plot(reg.miglia$fitted,reg.miglia$residuals)
> plot(reg.miglia2$fitted,reg.miglia2$residuals)
> plot(anno,reg.miglia$residuals)
> plot(anno,reg.miglia2$residuals)
Dal confronto dei residui prima e dopo la trasformazione della variabile di-
pendente, possiamo concludere che il ricorso alla trasformata logaritmica di
miglia ha ridotto gli andamenti sistematici, ma permangono degli schemi
di variazione che sono indice di un non perfetto adattamento ai dati. In
particolare, osserviamo una forma parabolica nei nuovi residui che potrebbe
indicare la necessità di includere una potenza della variabile anno nel modello
di regressione. Ritorneremo su questo punto nel paragrafo 5.4, quando verrà
trattata la regressione multipla. Inoltre, cogliamo la presenza di due residui
relativamente elevati. Verifichiamo a quali osservazioni corrispondono.
> identify(anno,reg.miglia2$residuals,n=2)
[1] 10 11
> miglia.aeree[c(10,11),]
miglia anno
10 5948 1946
11 6109 1947
> par(mfrow=c(1,1))
> plot(anno,miglia)
I due residui elevati corrispondono ai due punti che nel diagramma di disper-
sione di miglia su anno si discostano dall’andamento fondo.
> par(mfrow=c(1,2))
> qqnorm(reg.miglia$residuals/sqrt(var(reg.miglia$residuals)))
> abline(0,1)
> qqnorm(reg.miglia2$residuals/sqrt(var(reg.miglia2$residuals)))
> abline(0,1)
Alcune deviazioni dalla retta di riferimento sono ancora osservabili nel Q-Q
plot normale.
> plot(anno,miglia)
> abline(reg.miglia$coef)
> plot(anno,log(miglia))
> abline(reg.miglia2$coef)
85
Per poter rappresentare i risultati del nuovo modello di regressione sulla scala
originaria dobbiamo ricorrere alla trasformata esponenziale:
> par(mfrow=c(1,1))
> plot(anno,miglia)
> abline(reg.miglia$coef)
> lines(anno,exp(reg.miglia2$fitted))
Complessivamente, possiamo dire che l’uso della trasformata logaritmica ha
migliorato l’adattamento del modello di regressione ai dati ma alcune discre-
panze sono ancora presenti che potrebbero richidere ulteriori manipolazioni
(cfr. paragrafo 5.4.2).
Per fare delle previsioni su valori futuri delle miglia aeree sulla base del
nuovo modello di regressione, dobbiamo nuovamente ricorrere alla trasforma-
ta esponenziale.
> prev=predict(reg.miglia2,data.frame(anno=c(1956:1960)),
+ interval="prediction", level=0.95)
fit lwr upr
1 10.33762 9.868664 10.80658
2 10.55450 10.078560 11.03044
3 10.77138 10.287907 11.25485
4 10.98826 10.496729 11.47979
5 11.20514 10.705053 11.70522
> prev.miglia=exp(prev)
> prev.miglia
fit lwr upr
1 30872.53 19315.51 49344.43
2 38349.64 23826.65 61724.79
3 47637.66 29375.22 77253.77
4 59175.17 36196.92 96740.29
5 73506.99 44580.57 121202.52
Particolare cautela è richiesta nella previsione in modelli log–lineari come
quello utilizzato in questo paragrafo. Essi infatti assumono un andamento
esponenziale che per molti fenomeni diventa irragionevole nel lungo periodo.
A titolo esemplificativo, sono disponibili per le miglia aeree le osservazioni
degli anni 1956–1960:
> effettive=c(22362, 25340, 25343, 29269, 30514)
Confrontiamole graficamente con le nostre previsioni.
> plot(anno, miglia,xlim=c(1937,1960),ylim=c(0,73507))
> lines(c(anno,1956:1960),c(exp(reg.miglia2$fitted),prev.miglia[,1]))
> points(1956:1960,effettive,col="red")
86
5.4 Esempi di regressione lineare multipla in
R
Tratteremo in questo paragrafo alcuni esempi di regressione lineare multipla,
ossia modelli in cui la variabile dipendente è espressa come funzione lineare
di più di una variabile esplicativa.
sr tasso di risparmio
pop15 % di popolazione sotto i 15 anni
pop75 % di popolazione sopra i 75 anni
dpi reddito pro-capite utillizzabile (a valori reali)
ddpi tasso di crescita di dpi
I valori presentati per le 5 variabili sono il risultato di una media fatta sugli
anni 1960–1970. Siamo interessati ad utilizzare questo insieme di dati per ve-
rificare la teoria di Modigliani, usando la variabile sr come variabile risposta
espressa in funzione delle restanti 4 variabili esplicative.
> data(LifeCycleSavings)
> attach(LifeCycleSavings)
> LifeCycleSavings
sr pop15 pop75 dpi ddpi
Australia 11.43 29.35 2.87 2329.68 2.87
Austria 12.07 23.32 4.41 1507.99 3.93
Belgium 13.17 23.80 4.43 2108.47 3.82
.... .......
Libya 8.89 43.69 2.07 123.58 16.71
Malaysia 4.71 47.20 0.66 242.69 5.08
> pairs(LifeCycleSavings)
87
Con il comando pairs(LifeCycleSavings) otteniamo una matrice di dia-
grammi di dispersione. Ogni colonna e ogni riga della matrice è associata ad
una variabile del data frame. Ad esempio, la prima riga mostra i diagrammi
di dispersione della variabile sr rispetto alle restanti variabili del data frame;
la prima colonna contiene i diagrammi di dispersione di ciasuna delle varia-
bili del data frame, esclusa sr, rispetto a sr (è in sostanza la versione riflessa
della prima riga). Tramite questo grafico, siamo in grado di capire quali
sono le relazioni bivariate tra tutte le variabili coinvolte; non solo la dipen-
denza della variabile risposta dalle variabili esplicative, ma anche le relazioni
esistenti tra le variabili esplicative stesse. Possiamo cosı̀ notare una leggera
dipendenza di segno negativo di sr da pop15 e una dipendenza più marcata
di segno positivo di sr da ddpi, mentre non si osserva alcuna particolare
forma di relazione tra sr e pop75 o dpi. È opportuno sottolineare che queste
relazioni bivariate sono spurie, ossia non tengono conto dell’effetto congiunto
di tutte le variabili. Notiamo inoltre una forte dipendenza di segno negativo
tra pop15 e le variabili pop75 e dpi, e una relazione di segno positivo tra
pop75 e dpi.
Partiamo da un modello di regressione multipla che include tutte e 4 le
variabili esplicative:
> mod=lm(sr~pop15+pop75+dpi+ddpi)
> summary(mod)
Call:
lm(formula = sr ~ pop15 + pop75 + dpi + ddpi)
Residuals:
Min 1Q Median 3Q Max
-8.2422 -2.6857 -0.2488 2.4280 9.7509
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 28.5660865 7.3545161 3.884 0.000334 ***
pop15 -0.4611931 0.1446422 -3.189 0.002603 **
pop75 -1.6914977 1.0835989 -1.561 0.125530
dpi -0.0003369 0.0009311 -0.362 0.719173
ddpi 0.4096949 0.1961971 2.088 0.042471 *
88
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
> par(mfrow=c(3,2))
> plot(mod$fitted,mod$residuals)
> plot(pop15,mod$residuals)
> plot(pop75,mod$residuals)
> plot(dpi,mod$residuals)
> plot(ddpi,mod$residuals)
Si nota una leggera tendenza della varianza dei residui ad aumentare con
pop15, per il resto, non si osservano preoccupanti andamenti sistematici.
Rileviamo dal grafico dei residui e ddpi un valore anomalo rispetto a que-
st’ultima variabile; verifichiamone la presenza nel diagramma di dispersione
di sr su ddpi:
> plot(ddpi,sr)
> par(mfrow=c(1,1))
> qqnorm(mod$residuals/sqrt(var(mod$residuals)))
> abline(0,1)
89
I punti seguono perfettamente la retta di riferimento, pertanto sembra ade-
guata l’ipotesi di normalità dei termini di errore εi . Complessivamente, l’ana-
lisi dei residui non ha evidenziato grosse deviazioni dall’ipotesi del modello,
il quale può essere ritenuto soddisfacente.
Possiamo ora interpretare i risultati inferenziali alla luce della teoria di
Modigliani. Delle 4 variabili che Modigliani propone come determinanti del
tasso di risparmio, solo due (di cui una marginalmente) risultano significative.
Inoltre, l’R2 del modello è piuttosto basso. Questo ci fa pensare che, oltre a
quelli considerati in questa analisi, vi siano altri i fattori che possono incidere
sul tasso di risparmio.
Poiché 2 delle 4 variabili esplicative considerate non risultato associate ad
un parametro significativamente diverso da 0, possiamo pensare di sempli-
ficare il modello senza perdere in capacità esplicativa rispetto alla variabile
risposta. Seguiamo una procedura all’indietro (backward selection) eliminan-
do la variabile che risulta meno significativa in base al corrispondente p–value,
ossia la variabile dpi :
> mod2=lm(sr~pop15+pop75+ddpi)
> summary(mod2)
Call:
lm(formula = sr ~ pop15 + pop75 + ddpi)
Residuals:
Min 1Q Median 3Q Max
-8.2539 -2.6159 -0.3913 2.3344 9.7070
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 28.1247 7.1838 3.915 0.000297 ***
pop15 -0.4518 0.1409 -3.206 0.002452 **
pop75 -1.8354 0.9984 -1.838 0.072473 .
ddpi 0.4278 0.1879 2.277 0.027478 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
90
significativa, ora risulta, seppure marginalmente, significativa: rifiuteremmo
l’ipotesi di nullità del parametro ad essa associato al livello 10%, ma l’ac-
cetteremmo al livello 5%. La spiegazione di questo cambiamento può essere
ritrovata nella relazione identificata all’inizio dell’analisi tra dpi e le variabili
pop75 e pop15. Spesso, quando tra variabili esplicative esiste una relazione,
l’eliminazione di una delle variabili ha effetti sulle stime del modello.
L’R2 di mod2 è diminuito rispetto a mod. Vale in generale che l’elimina-
zione di una o più variabili porti a una riduzione dell’R2 . Tuttavia, se le
variabili eliminate sono non significative, anche la riduzione dell’R2 è “non
significativa”.
Non sembra opportuno procedere con un ulteriore semplificazione del mo-
dello, dato che tutte le variabili incluse hanno un ruolo nello spiegare sr. Pos-
siamo allora rivedere le nostre conclusioni riguardo alla teoria di Modigliani.
Delle 4 variabili proposte dall’economista 3 risultano rilevanti nel determi-
nare il tasso di risparmio. Tuttavia, l’R2 del modello selezionato è piuttosto
basso e permane il dubbio che altre variabili non considerate influenzino il
fenomeno del risparmio.
Concludiamo l’esempio, trattando il problema della previsione. Supponia-
mo, ad esempio, di essere interessati a prevedere il tasso di risparmio sr corri-
spondente a (pop15=33, pop75=2, ddpi=3) e (pop15=37, pop75=2, ddpi=3),
in base al modello di regressione multipla stimato mod2. A questo fine, si uti-
lizza ancora la funzione predict, ma nel data frame delle nuove osservazioni
dovremmo precisare i valori di tutte le variabili esplicative del modello:
> predict(mod2,data.frame(pop15=c(33,37),pop75=c(2,2),ddpi=c(3,3)),
+ interval="prediction",level=0.95)
fit lwr upr
1 10.828684 3.077458 18.57991
2 9.021574 1.355349 16.68780
91
> reg.miglia3=lm(log.miglia~anno + I(anno^2))
> summary(reg.miglia3)
Call:
lm(formula = log.miglia ~ anno + I(anno^2))
Residuals:
Min 1Q Median 3Q Max
-0.225215 -0.098130 -0.005284 0.045813 0.370831
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -1.949e+04 4.737e+03 -4.115 0.000810 ***
anno 1.982e+01 4.868e+00 4.072 0.000886 ***
I(anno^2) -5.038e-03 1.251e-03 -4.028 0.000973 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
> par(mfrow=c(2,2))
> plot(reg.miglia3$fitted, reg.miglia3$residuals)
> plot(anno, reg.miglia3$residuals)
> plot(anno^2, reg.miglia3$residuals)
> qqnorm(reg.miglia3$residuals/sqrt(var(reg.miglia3$residuals)))
> abline(0,1)
Non si notano sistematicità nei grafici dei residui rispetto ai valori stimati
e alle variabili esplicative. Anche il Q-Q plot normale è migliorato rispetto
92
al modello (5.5). Complessivamente, possiamo ritenere il nuovo modello di
regressione soddisfacente.
Tracciamo il grafico della curva di regressione stimata sul diagramma di
dispersione di miglia rispetto a anno:
> par(mfrow=c(1,1))
> plot(anno,miglia)
> lines(anno,exp(reg.miglia2$fitted))
> lines(anno,exp(reg.miglia3$fitted),col="red",lty=2)
> prev2=predict(reg.miglia3,data.frame(anno=c(1956:1960)),
+ interval="prediction", level=0.95)
> prev2
fit lwr upr
1 9.984959 9.595617 10.37430
2 10.096038 9.673105 10.51897
3 10.197041 9.732421 10.66166
4 10.287969 9.773647 10.80229
5 10.368820 9.797029 10.94061
Si noti che nello specificare i valori futuri per la variabile esplicativa è suf-
ficiente precisare i nuovi punti per anno: R si preoccuperà di calcolare la
potenza di anno necessaria per la previsione. Facciamo un confronto con
le precedenti previsioni e con i valori effettivamente osservati per gli anni
1956–1960:
> prev.miglia2=exp(prev2)
> prev.miglia2
fit lwr upr
1 21697.64 14700.21 32025.91
2 24246.75 15884.59 37011.04
3 26823.71 16855.30 42687.53
93
4 29377.04 17564.71 49133.19
5 31850.86 17980.25 56421.76
> prev.miglia
fit lwr upr
1 30872.53 19315.51 49344.43
2 38349.64 23826.65 61724.79
3 47637.66 29375.22 77253.77
4 59175.17 36196.92 96740.29
5 73506.99 44580.57 121202.52
> effettive
[1] 22362 25340 25343 29269 30514
Anche in termini previsivi il nuovo modello si comporta meglio di (5.5).
94
Il problema è la scelta del grado m del polinomio più appropriato.
Una prima precisazione riguardo a modelli di regressione polinomiale è
che spesso l’uso di potenze relativamente elevate della variabile esplicativa
conduce a problemi di stabilità delle stime. Un modo per superare questo
ostacolo è di lavorare con una versione standardizzata della variabile espli-
cativa, ad esempio sottraendo alla variabile stessa la sua media. Questa è la
strada che seguiremo in questo esempio, definendo la nuova variabile
> times.st=times-mean(times)
Un modo per scegliere il grado del polinomio (non è l’unico, né necessa-
riamente il migliore) è stimare inizialmente un polinomio di grado elevato,
più alto di quello che verosimilmente sarà appropriato per i dati in esame, e
procedere ad una eliminazione all’indietro, sfruttando la funzione anova di
R. Per il data frame mcycle, il diagramma di dispersione suggerisce che per
cogliere l’andamento dei dati sarà necessario un polinomio di grado piuttosto
elevato. Partiamo allora da un modello con polinomio di grado 15.
> pol15=lm(accel~times.st+I(times.st^2)+I(times.st^3)+I(times.st^4)+
+ I(times.st^5)+ I(times.st^6)+I(times.st^7)+I(times.st^8)+I(times.st^9)+
+ I(times.st^10)+I(times.st^11)+I(times.st^12)+I(times.st^13)+
+ I(times.st^14)+I(times.st^15))
> anova(pol15)
Analysis of Variance Table
Response: accel
Df Sum Sq Mean Sq F value Pr(>F)
times.st 1 27079 27079 51.6676 6.659e-11 ***
I(times.st^2) 1 17221 17221 32.8575 7.870e-08 ***
I(times.st^3) 1 57499 57499 109.7107 < 2.2e-16 ***
I(times.st^4) 1 45 45 0.0866 0.7690391
I(times.st^5) 1 60417 60417 115.2781 < 2.2e-16 ***
I(times.st^6) 1 7040 7040 13.4331 0.0003730 ***
I(times.st^7) 1 23592 23592 45.0142 7.345e-10 ***
I(times.st^8) 1 26590 26590 50.7347 9.268e-11 ***
I(times.st^9) 1 1016 1016 1.9391 0.1664100
I(times.st^10) 1 20027 20027 38.2132 9.556e-09 ***
I(times.st^11) 1 588 588 1.1211 0.2918630
I(times.st^12) 1 5415 5415 10.3317 0.0016902 **
I(times.st^13) 1 218 218 0.4156 0.5203935
I(times.st^14) 1 34 34 0.0639 0.8008214
I(times.st^15) 1 123 123 0.2340 0.6294789
Residuals 117 61319 524
95
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
> pol12=lm(accel~times.st+I(times.st^2)+I(times.st^3)+I(times.st^4)+
+ I(times.st^5)+ I(times.st^6)+I(times.st^7)+I(times.st^8)+I(times.st^9)+
+ I(times.st^10)+I(times.st^11)+I(times.st^12))
> summary(pol12)
Call:
lm(formula = accel ~ times.st + I(times.st^2) + I(times.st^3) +
I(times.st^4) + I(times.st^5) + I(times.st^6) + I(times.st^7) +
I(times.st^8) + I(times.st^9) + I(times.st^10) + I(times.st^11) +
I(times.st^12))
Residuals:
Min 1Q Median 3Q Max
-75.781 -12.284 1.046 11.995 50.613
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -6.536e+01 4.743e+00 -13.782 < 2e-16 ***
times.st 2.398e+01 1.659e+00 14.457 < 2e-16 ***
I(times.st^2) 1.044e+00 2.455e-01 4.254 4.19e-05 ***
I(times.st^3) -4.078e-01 4.248e-02 -9.601 < 2e-16 ***
I(times.st^4) -4.255e-03 3.382e-03 -1.258 0.210865
I(times.st^5) 2.598e-03 3.845e-04 6.756 5.40e-10 ***
I(times.st^6) -6.008e-06 1.660e-05 -0.362 0.718033
96
I(times.st^7) -7.787e-06 1.575e-06 -4.944 2.52e-06 ***
I(times.st^8) 7.794e-08 3.369e-08 2.314 0.022393 *
I(times.st^9) 1.111e-08 2.981e-09 3.728 0.000295 ***
I(times.st^10) -1.745e-10 4.141e-11 -4.215 4.86e-05 ***
I(times.st^11) -6.110e-12 2.117e-12 -2.886 0.004625 **
I(times.st^12) 1.239e-13 3.817e-14 3.245 0.001520 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
> plot(pol12$fitted,pol12$residuals)
> plot(times.st,pol12$residuals)
> plot(times.st^2,pol12$residuals)
> plot(times.st^3,pol12$residuals)
> plot(times.st^4,pol12$residuals)
> qqnorm(pol12$residuals/sqrt(var(pol12$residuals)))
> abline(0,1)
La variabilità dei residui sembra dipendere dal valore delle variabili espli-
cative. Questa è una violazione delle ipotesi del modello che ci fà dubitare
della sua bontà. Il Q-Q plot normale mostra alcune deviazioni, ma nulla di
particolarmente preoccupante.
È chiaro il motivo della dipendenza della varianza dei residui dalla variabile
esplicativa: per valori relativamente bassi del tempo le osservazioni seguono
da vicino il polinomio, ma la loro variabilità attorno alla curva stimata cre-
sce a tempi di impatto più elevati. In conclusione, il modello sembra cogliere
alcuni andamenti di fondo delle osservazioni, ma presenta delle carenze che
non sono colmabili con il ricorso a polinomi di grado più elevato. Soluzioni
a questo problema potrebbero essere trovate in trasformazioni della varia-
bile dipendente o nel ricorso a strumenti statistici diversi dalla regressione
polinomiale, ma non verrano qui considerate.
97
Come precisato nel paragrafo 5.4.2 è bene essere cauti nelle previsio-
ni basate su una regressione polinomiale, perché gli andamenti al di fuori
del campo di osservazione potrebbero differire da quelli colti dal modello.
Prevediamo il valore dell’accelerazione corrispondente a times=20:30:
> prev=predict(pol12,data.frame(times.st=20:30-mean(times)),
+ interval="prediction",level=0.95)
> prev
fit lwr upr
1 -116.950714 -162.97370 -70.9277294
2 -122.029313 -168.17997 -75.8786519
3 -119.190976 -165.39070 -72.9912530
4 -108.655402 -154.80079 -62.5100145
5 -91.526718 -137.54130 -45.5121333
6 -69.618335 -115.50011 -23.7365565
7 -45.198260 -91.02735 0.6308305
8 -20.691938 -66.58819 25.2043179
9 1.618239 -44.43782 47.6742938
10 19.859817 -26.37341 66.0930394
11 32.772603 -13.57995 79.1251518
> points(20:30, prev[,1],col="red")
Nella previsione, abbiamo standardizzato i “nuovi” valori della variabile
esplicativa, sottraendo la media di times.
5.5 Esercizi
Esercizio 1
Si consideri il data frame cereali introdotto al paragrafo 1.9 e analiz-
zato parzialmente nel Capitolo 2. Si studi l’andamento della variabile
calories (quantità di calorie per porzione) in funzione della variabile
fat (quantità di grassi per porzione) attraverso un opportuno model-
lo di regressione. A questo fine, si presti attenzione alla osservazione
corrispondente all’unità 31, già valutata anomala al Capitolo 2. Infine,
in base al modello stimato si prevedano i valori di calories corrispon-
denti a valori di fat tra 1 e 8 con un passo pari a 0.2. Si tracci sul
diagramma di dispersione dei dati i valori previsti e i corrispondenti
intervalli di previsione al livello 99%.
Esercizio 2
Nella libreria MASS di Venables e Ripley è incluso il data frame mammals
che fornisce per 62 specie di mammiferi i pesi medi del cervello in gram-
mi (colonna brain) e del corpo in chilogrammi (colonna body). Si vuole
98
spiegare le dipendenza del peso medio del cervello dal peso medio del
corpo. A questo fine, si acceda al data frame, come descritto al para-
grafo 5.4.3 e si costruiscano il diagramma di dispersione della variabile
brain sulla variabile body e il diagramma di dispersione della variabile
brain trasformata attraverso il logaritmo rispetto alla variabile body
anch’essa trasformata attraverso il logaritmo. Alla luce dei due grafici
ottenuti, quale modello di regressione di brain su body vi sembra più
appropriato? Si stimi e si valuti l’adeguatezza del modello proposto.
Esercizio 3
Nella libreria MASS di Venables e Ripley è incluso il data frame wtloss.
Esso riporta il peso in chilogrammi (colonna Weight) di un paziente
obeso rilevato in corrispondenza di 52 istanti temporali (colonna Days)
durante 8 mesi di un programma di riabilitazione. È di interesse stu-
diare l’andamento temporale del peso, ossia la dipendenza di Weight
da Days. A questo fine, si acceda al data frame e si analizzi il model-
lo di regressione lineare semplice della variabile Weight rispetto alla
variabile Days. Quale modifiche al precedente modello di regressione
vengono suggerite dall’analisi dei residui? Si proponga e si studi un
modello di regressione alternativo alla retta precedentemente stimata.
(Suggerimento: si consideri la possibilità di ricorrere ad una regressio-
ne polinomiale.) In base al nuovo modello si preveda il peso che si
sarebbe raggiunto al termine del trattamento qualora il programma di
riabilitazione fosse stato prolungato sino al giorno 256.
Esercizio 4
È stato messo a disposizione degli studenti il file fuel.txt che per
48 stati americani, specificati dalla prima colonna, riporta le seguenti
quantità:
99
ci si avvalga anche della funzione pairs introdotta al paragrafo 5.4.1).
Partendo dal modello di regressione multipla che include tutte e 4 le
variabili esplicative, tramite una procedura all’indietro, si selezioni le
variabili con un effetto significativo su FUEL. Per il modello finale si
conduca un’analisi della bontà di adattamento ai dati e di verifica delle
ipotesi della regressione. Si preveda, inoltre, il valore di FUEL corri-
spondente a livelli di tassazione pari a 4.5 e 10.5, mentre le restanti
variabili esplicative sono fissate ai rispettivi valori medi.
100
Indice
1 Introduzione a R 1
1.1 Che cos’è R . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Iniziare e chiudere una sessione di R . . . . . . . . . . . . . . 1
1.3 Un pò di aritmetica, matematica e logica... . . . . . . . . . . . 2
1.4 Assegnazioni di valori . . . . . . . . . . . . . . . . . . . . . . . 3
1.5 Salvataggio dei dati . . . . . . . . . . . . . . . . . . . . . . . . 4
1.6 I vettori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6.1 Creazione di un vettore . . . . . . . . . . . . . . . . . . 5
1.6.2 Manipolazione dei vettori . . . . . . . . . . . . . . . . 6
1.6.3 Estrazione degli elementi da un vettore . . . . . . . . . 8
1.7 Creazione e manipolazione di matrici . . . . . . . . . . . . . . 9
1.8 I data frame . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.9 Lettura e scrittura di un file . . . . . . . . . . . . . . . . . . . 15
1.10 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2 Statistica descrittiva 19
2.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2 Tabelle di frequenza . . . . . . . . . . . . . . . . . . . . . . . 19
2.3 Indici di posizione e variabilità . . . . . . . . . . . . . . . . . 21
2.4 Grafici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.4.1 Grafici per variabili qualitative . . . . . . . . . . . . . 24
2.4.2 Grafici per variabili quantitative . . . . . . . . . . . . . 25
2.4.3 Diagrammi di dispersione . . . . . . . . . . . . . . . . 29
2.5 Misure di dipendenza tra due variabili quantitative . . . . . . 31
2.6 Salvataggio dei grafici . . . . . . . . . . . . . . . . . . . . . . . 33
2.7 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3 Probabilità 35
3.1 Distribuzioni di probabilità . . . . . . . . . . . . . . . . . . . 35
3.2 Simulazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.3 Legge dei grandi numeri e teorema del limite centrale . . . . . 39
3.4 Tecniche di campionamento . . . . . . . . . . . . . . . . . . . 41
101
3.5 Confronti con la distribuzione normale . . . . . . . . . . . . . 42
3.6 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
102