laboratorio informatico-statistico con r

Transcript

laboratorio informatico-statistico con r
LABORATORIO
INFORMATICO-STATISTICO
CON R
Mariantonietta Ruggieri
Dipartimento di Scienze statistiche e matematiche “S.Vianelli”
Università degli studi di Palermo
Prefazione
Questa dispensa è stata creata per gli studenti di “Laboratorio informatico-statistico” del Corso di laurea
in S.I.G.A.D. (Statistica e Informatica per la Gestione e l’Analisi dei Dati) della Facoltà di Economia di
Palermo.
Il corso di “Laboratorio informatico-statistico” si propone di fornire agli studenti strumenti informatici di
supporto agli argomenti trattati nei corsi istituzionali di Statistica descrittiva (MODULO 1) e inferenziale
(MODULO 2), pertanto prevede che tali conoscenze siano preliminari.
In Appendice si riportano alcuni esercizi con le relative soluzioni. Gli studenti del S.I.G.A.D. possono
scaricare i dataset utilizzati collegandosi con il sito del Corso di laurea, il cui indirizzo è:
http://dssm.unipa.it/sigad, cliccando sul link “Ruggieri” e scegliendo la cartella “DATASET_R”.
Si ricorda che per poter scaricare il materiale didattico bisogna prima effettuare il login.
2
INDICE
MODULO 1
5
1 L’ambiente R
6
1.1 Cosa è R
1.1.1 Introduzione all’ambiente statistico R
1.1.2 Come iniziare con R
1.2 Gli oggetti
1.2.1 Vettori e variabili
1.2.2 Matrici
1.3 Matematica con R
1.3.1 Operazioni con vettori e matrici
1.3.2 Risoluzione di equazioni e sistemi
1.3.3 Massimi e minimi di una funzione
1.4 La gestione degli oggetti
1.4.1 Estrarre elementi da vettori o matrici
1.4.2 Il workspace
1.4.3 Tipologie di oggetti
1.5
Funzioni, script o programmi
1.6
Test e cicli
1.7
Input ed Output
1.7.1 Come salvare l’output
1.7.2 Importare dati in formato testo
1.8
Packages di R
2 Statistica descrittiva con R
6
6
6
7
7
9
10
10
12
14
15
15
16
18
20
21
23
23
23
24
25
2.1 Immissione dei dati
2.1.1 Classificazione delle variabili
2.1.2 Dataset statistici
2.2 Serie di dati e distribuzioni di frequenza
2.2.1 Distribuzioni di frequenza per valori singoli
2.2.2 Distribuzioni di frequenza per classi di valori
2.3 Rappresentazioni grafiche
2.3.1 Grafico a colonne
2.3.2 Grafico a torta
2.3.3 Diagramma cartesiano
2.3.4 Istogramma e poligono di frequenza
2.3.5 Funzione di ripartizione
2.3.6 Boxplot
2.4 Indici di sintesi
2.4.1 Le medie
2.4.2 Gli indici di eterogeneità
2.4.3 Gli indici di variabilità
2.4.4 Gli indici di asimmetria e di curtosi
3
25
25
26
29
29
30
32
32
33
33
34
36
39
40
40
42
43
45
3 Relazioni tra variabili
47
3.1 L’analisi delle tabelle di contingenza
3.2 La regressione lineare semplice
3.3 La dipendenza in media: il rapporto di correlazione
47
52
58
MODULO 2
59
4 Calcolo delle probabilità con R
60
4.1 Esperimenti casuali
4.2 Calcolo combinatorio
4.3 Valore atteso e varianza di variabili casuali
4.4 Variabili casuali discrete
4.4.1 v.c. binomiale
4.4.2 v.c. bernoulliana
4.4.3 v.c. geometrica
4.4.4 v.c. binomiale negativa
4.4.5 v.c. ipergeometrica
4.4.6 v.c. di Poisson
4.5 Variabili casuali continue
4.5.1 v.c. normale o di Gauss
4.5.2 v.c. uniforme
4.5.3 v.c. chi-quadrato
4.5.4 v.c. t di Student
4.5.5 v.c. F
4.5.6 v.c. esponenziale
4.5.7 v.c. gamma
4.5.8 v.c. beta
4.6 Simulazione di variabili casuali
5 Campionamento e inferenza
60
60
61
65
65
66
67
68
69
69
70
70
74
75
76
77
78
78
80
81
83
5.1 Legge dei grandi numeri
5.2 Teorema centrale del limite
5.3 Funzione di (log)verosimiglianza
5.4 Intervalli di confidenza
5.4.1 IC per la media
5.4.2 IC per una proporzione
5.4.3 IC per la varianza
5.5 Verifica di ipotesi
5.5.1 Verifica di ipotesi per la media
5.5.2 Verifica di ipotesi per una proporzione
5.5.3 Verifica di ipotesi per la varianza
Appendice
Esercizi modulo 1
Esercizi modulo 2
Soluzioni esercizi modulo 1
Soluzioni esercizi modulo 2
83
85
87
90
90
93
94
95
96
97
98
101
102
105
109
124
4
MODULO 1
5
1 L’ambiente R
1.1 Cosa è R
1.1.1 Introduzione all’ambiente statistico R
R più che un software si può definire un ambiente statistico di programmazione ad oggetti1, che
consente di manipolare quantità di dati consistenti, effettuare calcoli, visualizzare informazioni e
grafici, trattare modelli statistici anche complessi.
Come S-PLUS ha origine dal linguaggio S2. Il nome “R” deriva probabilmente dalle iniziali del
nome dei due sviluppatori originari: Robert Gentleman e Ross Ihaka.
R è un linguaggio free, sotto la licenza GNU - General Pubblic Licence - della Free Software
Foundation, dunque si può scaricare gratuitamente da Internet all’indirizzo: http://cran.r-project.org/
E’ curato da statistici ed esperti di informatica soprattutto di fama internazionale ed è in costante
sviluppo. Il gruppo di sviluppatori di R costituisce l’R Development Core Team.
R è cross-platform, ossia è compatibile con vari processori e sistemi operativi ed è open-source,
cioè è possibile accedere al codice interno e proporne modifiche.
1.1.2 Come iniziare con R
Se R è stato installato correttamente, al suo avvio si apre una finestra, chiamata “R Console”, che
fornisce le seguenti informazioni:
R : Copyright 2004, The R Foundation for Statistical Computing
Version 2.0.1 (2004-11-15), ISBN 3-900051-07-0
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.
R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.
Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for a HTML browser interface to help.
Type 'q()' to quit R.
>
Quest’ultimo è il “prompt” di R, dopo il quale possono essere inseriti tutti i comandi.
I comandi possono essere separati da un punto e virgola o semplicemente essere immessi in una
nuova linea, digitando il tasto “Invio”.
Il carattere + sta ad indicare che il comando continua nella linea successiva.
I comandi già eseguiti possono essere richiamati da tastiera mediante i tasti freccia verticali ( ↑, ↓) e
modificati mediante i tasti freccia orizzontali (←, →).
Bisogna tener presente che R è case-sensitive, cioè i caratteri minuscoli sono considerati diversi dai
caratteri maiuscoli.
1
2
vettori, funzioni, tabelle, grafici
il nome deriva dal linguaggio C, in inglese "SEE"
6
All’avvio di R vengono fornite alcune indicazioni. Ad esempio viene suggerito il comando per
uscire dall'ambiente R:
>q()
Tale procedura è consentita anche dal menu dell’interfaccia grafica (File – Exit oppure ×).
E’ possibile ottenere istruzioni sui comandi, attraverso l’help on-line, fortemente consigliato. Le
due istruzioni sono equivalenti:
>help(nome comando)
>?nome comando
esempi:
>help(q)
>?q
Alcuni comandi necessitano delle virgolette, come ad esempio for:
>help("for")
>?"for"
Informazioni più dettagliate su come utilizzare l’help, si possono ottenere digitando il comando:
>?help
E’ possibile aprire una pagina di help in formato html attraverso il comando:
>help.start()
Per alcune dimostrazioni si può utilizzare il comando:
>demo()
ad esempio
>demo(graphics)
mostra una serie di grafici che è possibile costruire con R.
1.2 Gli oggetti
1.2.1 Vettori e variabili
Gli elementi che R consente di creare e gestire sono gli oggetti. Gli oggetti più semplici sono gli
scalari e i vettori.
L’istruzione di assegnazione è <-; il simbolo = è consentito, ma fortemente sconsigliato.
Dunque, volendo assegnare ad una variabile x il valore 7, il comando da utilizzare è il seguente:
7
> x<-7
Per visualizzare il contenuto dell’oggetto x, basta richiamare x:
>x
[1] 7
L’output è preceduto da [1], che sta ad indicare la posizione del primo elemento del vettore x. x,
sebbene sia uno scalare, viene interpretato come vettore di lunghezza 1.
Creiamo un vettore con più elementi. Le seguenti tre istruzioni sono equivalenti, ma la seconda e la
terza non sono consigliate:
> y<-c(2,6,8,9,3)
> c(2,6,8,9,3)->y
> assign("y",c(2,6,8,9,3))
Il comando "c" viene utilizzato per concatenare gli elementi.
Gli elementi possono anche essere inseriti uno per volta con l’istruzione “scan()”, separati da spazio
o da un Invio, di cui l’ultimo deve essere a vuoto:
> y<-scan()
1: 2 6 8 9 3
6:
Read 5 items
> y<-scan()
1: 2
2: 6
3: 8
4: 9
5: 3
6:
Read 5 items
Se richiamiamo y, otteniamo i valori in esso contenuti:
>y
[1] 2 6 8 9 3
Per creare un vettore x che contiene i primi 7 numeri naturali, utilizziamo la seguente istruzione:
> x<-1:7
>x
[1] 1 2 3 4 5 6 7
Una successione di numeri può anche essere creata col comando “seq”, che consente di specificare
anche il passo o il numero n (length) degli elementi della successione3:
3
Ricordiamo che il passo di una successione è dato da: (x(n)-x(1))/(n-1), dove x(1) ed x(n) sono i valori estremi della serie
ordinata.
8
> x<-seq(1,7)
>x
[1] 1 2 3 4 5 6 7
> x<-seq(-2,8,2)
>x
[1] -2 0 2 4 6 8
> y<-seq(0,1,length=11)
>y
[1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
1.2.2 Matrici
Costruiamo un vettore z che contiene i primi 20 numeri naturali:
> z<-1:20
>z
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Volendo creare una matrice A, che contiene gli stessi elementi del vettore z, organizzati in 5 righe e
4 colonne, il comando da utilizzare è “matrix”:
> A<-matrix(z,5,4)
>A
[,1] [,2] [,3] [,4]
[1,] 1 6 11 16
[2,] 2 7 12 17
[3,] 3 8 13 18
[4,] 4 9 14 19
[5,] 5 10 15 20
Si noti come R riempia le matrici per colonna. Per riempire la matrice per riga, bisogna aggiungere
l’opzione “byrow=TRUE”:
> B<-matrix(z,5,4,byrow=TRUE) # riempimento per riga
>B
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
[3,] 9 10 11 12
[4,] 13 14 15 16
[5,] 17 18 19 20
Il cancelletto # è indicatore di commento; tutto ciò che segue a questo simbolo non viene
interpretato da R come comando.
Se si vuole creare una matrice di elementi tutti uguali a 0 oppure ad 1, basta inserire come primo
argomento, rispettivamente, i valori 0 e 1 una sola volta:
9
> C<-matrix(0,4,3)
>C
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
[3,] 0 0 0
[4,] 0 0 0
> C<-matrix(1,4,3)
>C
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
[4,] 1 1 1
Se il primo argomento non viene specificato, R creerà una matrice di elementi NA, dove NA,
acronimo di “not available”, definisce i valori mancanti:
> C<-matrix(,4,3)
>C
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
[3,] NA NA NA
[4,] NA NA NA
1.3 Matematica con R
1.3.1 Operazioni con vettori e matrici
Se x è uno scalare e y un vettore:
>x
[1] 7
>y
[1] 2 6 8 9 3
il comando
> x*y
[1] 14 42 56 63 21
darà come risultato il prodotto di uno scalare per un vettore, mentre un vettore moltiplicato per se
stesso:
> y*y
[1] 4 36 64 81 9
fornirà un vettore che ha come elementi gli elementi al quadrato di y.
L’istruzione “t”, serve per effettuare la trasposizione di un vettore/matrice:
10
> t(y)
[,1] [,2] [,3] [,4] [,5]
[1,] 2 6 8 9 3
> A<-matrix(1:20,5,4)
> t(A)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 6 7 8 9 10
[3,] 11 12 13 14 15
[4,] 16 17 18 19 20
Volendo utilizzare l’algebra lineare, per effettuare un prodotto matriciale, si utilizza l’istruzione
“%*%”, dunque per eseguire le operazioni
- y'×y
- y×y'
i comandi da utilizzare sono rispettivamente:
> t(y)%*%y
[,1]
[1,] 194
> y%*%y
[,1]
[1,] 194
> y%*%t(y)
[,1] [,2] [,3] [,4] [,5]
[1,] 4 12 16 18 6
[2,] 12 36 48 54 18
[3,] 16 48 64 72 24
[4,] 18 54 72 81 27
[5,] 6 18 24 27 9
Come si può notare, per convenzione, le istruzioni
> t(y)%*%y
> y%*%y
sono equivalenti.
Per moltiplicare ciascun elemento di un vettore x
> x<-c(5,8,2,1,4)
per ciascun elemento di un altro vettore y, è possibile utilizzare l’istruzione “%o%”:
> x%o%y
[,1] [,2] [,3] [,4] [,5]
[1,] 10 30 40 45 15
11
[2,]
[3,]
[4,]
[5,]
16
4
2
8
48
12
6
24
64 72 24
16 18 6
8 9 3
32 36 12
che è equivalente all’istruzione
> x%*%t(y)
[,1] [,2] [,3] [,4] [,5]
[1,] 10 30 40 45 15
[2,] 16 48 64 72 24
[3,] 4 12 16 18 6
[4,] 2 6 8 9 3
[5,] 8 24 32 36 12
Lo stesso risultato dà l’istruzione “%x%”:
> x%x%y
[1] 10 30 40 45 15 16 48 64 72 24 4 12 16 18 6 2 6 8 9 3 8 24 32 36 12
ma sotto forma di vettore.
I vettori che hanno come elementi la somma, la differenza, il prodotto ed il rapporto degli elementi
corrispondenti dei vettori x ed y, possono essere determinati, rispettivamente, con le seguenti
istruzioni:
> x+y
[1] 7 14 10 10 7
> x-y
[1] 3 2 -6 -8 1
> x*y
[1] 10 48 16 9 12
> x/y
[1] 2.5000000 1.3333333 0.2500000 0.1111111 1.3333333
E’ possibile eseguire altre operazioni con i vettori. Per ulteriori approfondimenti si può utilizzare
l’help on-line:
> ?"+"
> example("+")
1.3.2
Risoluzione di equazioni e sistemi
Per risolvere l'equazione p(x)=0, dove p(x)=a0+a1x+…+anxn, l’istruzione da utilizzare è “polyroot”,
che ha come argomento il vettore dei coefficienti. Supponiamo, ad esempio, di voler risolvere
l’equazione 1-4x+4x2=0:
> x<-c(1,-4,4)
> polyroot(x)
[1] 0.5+0i
0.5-0i
12
In questo caso, essendo il discriminante uguale a zero, le due radici sono reali e coincidenti. In
generale, comunque, R fornisce tutte le n soluzioni possibili, anche quelle non reali.
Un’altra istruzione che consente di determinare le radici di un’equazione, quando p(x) è una
funzione generica qualsiasi, ma sempre di una sola variabile, è “uniroot”. Per i dettagli si utilizzi
l’help on-line:
> ?uniroot
Per la risoluzione di un sistema lineare del tipo
Ax=b
si utilizza la funzione “solve”. Ad esempio:
> A<-matrix(c(4,2,-5,7),2,2)
> b<-c(5,3)
> x<-solve(A,b)
>x
[1] 1.31578947
0.05263158
> A<-matrix(c(2,3,4,1,2,-5,8,-1,7),3,3)
> b<-c(2,3,1)
> x<-solve(A,b)
>x
[1] 0.73298429
0.40837696 0.01570681
Se b è una matrice:
> A<-matrix(c(4,2,-5,7),2,2)
> b<-matrix(c(5,-3,1,4),2,2)
> x<-solve(A,b)
>x
[,1]
[,2]
[1,] 0.5263158
0.7105263
[2,] -0.5789474
0.3684211
Per calcolare l’inversa di A, dunque, basta che b sia la matrice identità; in tal caso, non è neanche
necessario specificarlo:
> solve(A)
[,1] [,2]
[1,] 0.18421053 0.1315789
[2,] -0.05263158 0.1052632
L’istruzione “eigen”, invece, consente di calcolare gli autovalori e gli autovettori di una matrice:
> A<-matrix(c(1,-1,-1,1),2)
>A
[,1] [,2]
[1,] 1 -1
[2,] -1 1
13
> eigen(A)
$values
[1] 2 0
$vectors
[,1]
[,2]
[1,] -0.7071068 -0.7071068
[2,] 0.7071068 -0.7071068
Si noti come nella definizione della matrice A è sufficiente specificare solo il numero delle righe.
1.3.3 Massimi e minimi di una funzione
Come vedremo più avanti (cfr.par.1.5), l’istruzione “function” definisce una funzione.
Consideriamo ad esempio la funzione f(x)=1-3x+2x2, di cui vogliamo calcolare il minimo.
L’istruzione “nlm” applica il metodo di Newton, dunque necessita di un valore iniziale per la
ricerca del minimo, mentre l’istruzione “optimize” usa metodi non lineari e necessita di un
intervallo di valori in cui effettuare la ricerca:
> f<-function(x) 1-3*x+2*x^2
> nlm(f,1)
$minimum
[1] -0.125
$estimate
[1] 0.7499997
$gradient
[1] 9.994228e-07
$code
[1] 1
$iterations
[1] 1
> optimize(f,c(-4,3))
$minimum
[1] 0.75
$objective
[1] -0.125
> f(0.75) # valore della funzione nel punto di ascissa 0.75
[1] -0.125
> plot(f,-4,3)
14
40
30
f (x)
20
10
0
-4
-3
-2
-1
0
1
2
3
x
L’istruzione “plot” consente di rappresentare graficamente la funzione nell’intervallo [–4, 3].
Questa istruzione verrà analizzata nei dettagli più avanti (cfr.par. 2.3).
1.4 La gestione degli oggetti
1.4.1 Estrarre elementi da vettori o matrici
Se si vuole accedere agli elementi di un vettore, basta richiamare il vettore seguito dalla posizione
dell’elemento che si vuole estrarre, racchiusa entro parentesi quadre:
> x<-seq(-2,8,2)
>x
[1] -2 0 2 4 6 8
> x[5]
[1] 6
Il comando “which” estrae le posizioni degli elementi di un vettore che soddisfano a determinate
condizioni:
> which(x<2)
[1] 1 2
> which((x>=2)&(x<7))
[1] 3 4 5
> z<-which((x<2)|(x>=5))
>z
[1] 1 2 5 6
> x[z]
[1] -2 0 6 8
Quest’ultimo comando richiama gli elementi che occupano, rispettivamente, le posizioni contenute
in z.
Gli operatori & e | sono gli operatori logici “and” e “or”.
Per accedere agli elementi di una matrice, bisogna specificare la riga e la colonna in cui si trova
l’elemento:
> A<-matrix(x,2,2)
>A
[,1] [,2]
15
[1,] -2 2
[2,] 0 4
> A[1,2]
[1] 2
> A<-matrix(x,2,3)
>A
[,1] [,2] [,3]
[1,] -2 2 6
[2,] 0 4 8
> A[2,2]
[1] 4
per estrarre un’intera riga o colonna, bisogna specificare la riga o la colonna cui si è interessati,
rispettivamente, prima e dopo la virgola:
> A[1,]
[1] -2 2 6
> A[,2]
[1] 2 4
1.4.2
Il workspace
L’elenco degli oggetti creati durante una o più sessioni di R costituiscono lo spazio di lavoro
(workspace); per visualizzarlo si possono utilizzare le seguenti due equivalenti istruzioni:
> ls()
> objects()
oppure è possibile ricorrere al menu dell’interfaccia grafica (Misc-List objects).
Per eliminare gli oggetti dal workspace, si utilizza il comando “rm”, seguito da parentesi tonde, che
racchiudono l’elenco degli oggetti da eliminare separati da virgola, ad esempio:
> rm(x,y,z,A,B)
Per eliminare tutti gli oggetti contemporaneamente, è possibile utilizzare il comando:
> rm(list=ls())
oppure il menu dell’interfaccia grafica (Misc-Remove all objects).
Per conoscere la cartella di lavoro corrente l’istruzione è:
> getwd()
Se si desidera cambiarla, ciò è possibile attraverso il menu dell’interfaccia grafica (File-Change dir)
oppure attraverso l’istruzione
> setwd()
in tal caso, bisogna specificare il percorso, all’interno delle parentesi tonde e fra virgolette,
ricordandosi di utilizzare tra una cartella e un’altra il back slash o il doppio slash.
16
E’ conveniente creare, prima di aprire una sessione, una propria cartella di lavoro e configurarla
direttamente, posizionandosi sull’icona che compare nel desktop per avviare R e cliccando sul tasto
destro del mouse (scegliere la voce proprietà).
Per conoscere i file contenuti nella cartella di lavoro l’istruzione è
> dir()
oppure dal menu:
File-Display file(s)
E’ possibile salvare tutte le istruzioni utilizzate in una sessione di lavoro. Dal menu:
File-Save History.
Il nome del file che contiene le istruzioni salvate avrà estensione “Rhistory”. Queste ultime possono
essere richiamate sempre attraverso il menu:
File-Load History
Gli oggetti creati possono essere salvati in un file che avrà estensione “Rdata”. L’istruzione è:
> save(elenco oggetti separati da virgola, file="nome file").
E’ possibile salvare tutti gli oggetti dal menu:
File-Save Workspace
e richiamarli:
File-Load Workspace.
L’istruzione equivalente, in quest’ultimo caso è:
> load("nome file").
Alla chiusura di una sessione di R si può scegliere, comunque, di salvare istruzioni e oggetti
contemporaneamente (Save workspace image).
E’ possibile anche salvare l’intera schermata, in formato testo. Dal menu:
File-Save to File.
Se, invece, si vuole pulire la schermata, durante una sessione di lavoro, dal menu:
Edit-Clear console.
Dalle situazioni di "empasse" si può uscire digitando
"."
17
oppure
")"
o semplicemente pigiando il tasto “ESC”
o, ancora, dal menu dell’interfaccia grafica:
Misc-Stop current computation.
1.4.3
Tipologie di oggetti
Il nome di un oggetto può essere un carattere alfanumerico e può contenere il punto, ma non deve
mai iniziare con un numero. E’ consigliabile non utilizzare alcuni nomi riservati, nomi di funzioni
od operatori, quali:
FALSE, TRUE, Inf, NA, NaN, NULL, break, else, for, function, if, in, next, repeat, while.
Non è conveniente, anche se ammesso,definire con "q" o "c" un oggetto.
I nomi delle funzioni non possono contenere caratteri particolari come, ad esempio, l’underscore.
Le diverse tipologie di oggetti che R può maneggiare sono:
character:
integer:
numeric:
complex:
logical:
stringhe o sequenze di caratteri;
numeri interi, con o senza segno;
numeri reali;
numeri complessi;
assumono i valori TRUE, FALSE, NA.
Questi oggetti possono essere scalari, vettori, matrici a due o più vie. Esiste poi in R la cosiddetta
“lista”, che è un insieme di oggetti di tipo diverso. Consideriamo, ad esempio, i seguenti oggetti:
> ogg1<-c("anna","marco","luca")
> ogg1
[1] "anna" "marco" "luca"
> ogg2<-complex(real=1:7,imaginary=-1:5)
> ogg2
[1] 1-1i 2+0i 3+1i 4+2i 5+3i 6+4i 7+5i
> ogg3<-c(TRUE,FALSE,FALSE,TRUE,FALSE)
> ogg3
[1] TRUE FALSE FALSE TRUE FALSE
> A<-matrix(c(1,-1,-1,1),2)
>A
[,1] [,2]
[1,] 1 -1
[2,] -1 1
> ogg4<-eigen(A) #autovalori e autovettori della matrice A
> ogg4
$values
[1] 2 0
$vectors
[,1]
[,2]
18
[1,] -0.7071068 -0.7071068
[2,] 0.7071068 -0.7071068
Creiamo una lista con l’istruzione “list”:
> lista<-list(ogg1,ogg2,ogg3,ogg4)
> lista
[[1]]
[1] "anna" "marco" "luca"
[[2]]
[1] 1-1i 2+0i 3+1i 4+2i 5+3i 6+4i 7+5i
[[3]]
[1] TRUE FALSE FALSE TRUE FALSE
[[4]]
[[4]]$values
[1] 2.000000e+00 9.860761e-32
[[4]]$vectors
[,1] [,2]
[1,] 0.7071068 0.7071068
[2,] -0.7071068 0.7071068
Per richiamare una componente della lista “lista”, ad esempio la 2°, specificare il nome della lista,
seguito dalla posizione della componente cui si è interessati, racchiusa tra parentesi quadre:
> lista[2]
[[1]]
[1] 1-1i 2+0i 3+1i 4+2i 5+3i 6+4i 7+5i
Per richiamare una componente di una componente, ad esempio la 1° componente della 4°
componente, l’istruzione è:
> lista[4][[1]]$values
[1] 2.000000e+00 9.860761e-32
Gli oggetti contenuti in una lista possono anche essere nominati nel seguente modo, in modo tale da
rendere più semplice l’accesso agli elementi della lista stessa:
> lista2<-list(n1=ogg1,n2=ogg2,n3=ogg3,n4=ogg4)
> lista2
$n1
[1] "anna" "marco" "luca"
$n2
[1] 1-1i 2+0i 3+1i 4+2i 5+3i 6+4i 7+5i
$n3
[1] TRUE FALSE FALSE TRUE FALSE
19
$n4
$n4$values
[1] 2.000000e+00 9.860761e-32
$n4$vectors
[,1] [,2]
[1,] 0.7071068 0.7071068
[2,] -0.7071068 0.7071068
Così, per richiamare la 3° componente della lista “lista2”, si utilizza l’istruzione:
> lista2$n3
[1] TRUE FALSE FALSE TRUE FALSE
mentre per richiamare la 1° componente della 4° componente, l’istruzione da utilizzare è:
> lista2$n4$values
[1] 2.000000e+00 9.860761e-32
E’ possibile interrogare R sulla tipologia, la classe e la struttura di un oggetto. Chiediamo, ad
esempio, informazioni sull’oggetto di nome “lista”:
> is.list(lista)
[1] TRUE
> class(lista)
[1] "list"
> str(lista)
List of 4
$ : chr [1:3] "anna" "marco" "luca"
$ : cplx [1:7] 1-1i 2+0i 3+1i ...
$ : logi [1:5] TRUE FALSE FALSE TRUE FALSE
$ :List of 2
..$ values : num [1:2] 2.00e+00 9.86e-32
..$ vectors: num [1:2, 1:2] 0.707 -0.707 0.707 0.707
1.5 Funzioni, script o programmi
Costruire una funzione con R è abbastanza semplice; il comando da utilizzare è “function”, che ha
come argomenti, racchiusi tra parentesi tonde, i nomi delle variabili.
Supponiamo di voler costruire una funzione che calcoli il prodotto fra due numeri x e y; tale
funzione la chiamiamo “per”:
> per<-function(x,y) x*y
Volendo, dunque, calcolare il prodotto di due numeri qualsiasi, basta richiamare la funzione e
specificare i due valori:
> per(5,2)
[1] 10
20
Per conoscere gli argomenti di una funzione si può utilizzare il comando “args” o “str”:
> args(per)
> str(per)
oppure il comando “help” se la funzione è già presente in R:
> help(nome funzione)
Il comando “body” consente di conoscere il codice di una funzione, mentre il comando “fix” apre
una finestra, che consente di modificarlo:
> body(per)
x*y
> fix(per)
Ovviamente, via via che si acquisirà dimestichezza, si costruiranno funzioni sempre più complesse,
che è conveniente salvare, per poi poterle all’occorrenza riutilizzare. Una funzione si può salvare in
un file di testo e successivamente richiamare dal menu:
File-Source R code
o digitando il comando “source”:
> source("nome file")
Gli script, o programmi, possono essere memorizzati e poi richiamati dal menù:
File-Nuovo script
File-Apri script
Per richiamare uno script si può anche cliccare semplicemente sulla finestrella gialla in alto a
sinistra.
1.6 Test e cicli
Un test tipico di un algoritmo verifica alcune condizioni ed è così strutturato:
if (condizione) istruzione else istruzione
Supponiamo, ad esempio, di voler modificare la funzione precedente, in modo tale che calcoli il
prodotto di due numeri x e y solo se (if) x>2 e (&) y<7, altrimenti (else) visualizzi la parola
“errore”:
> per<-function(x,y)
>{
> if ((x>2)&(y<7))
> x*y
> else
21
> "errore"
>}
> per(4,3)
> per(3,8)
Come si può notare, il corpo di una funzione più complessa va inserito all’interno di parentesi
graffe.
La parte relativa ad “else”, se non è necessaria, può essere omessa.
Abbiamo già incontrato gli operatori logici “&” e “|”; altri operatori logici sono “&&” e “||”. I primi
due eseguono un controllo logico termine a termine tra due vettori, mentre gli ultimi due eseguono
il controllo in sequenza da sinistra a destra e si arrestano fornendo il primo risultato valido. Ad
esempio:
> x<-c(FALSE,TRUE,TRUE,FALSE,TRUE)
> y<-c(TRUE,FALSE,TRUE,FALSE,FALSE)
> x&y
[1] FALSE FALSE TRUE FALSE FALSE
> x&&y
[1] FALSE
n.b. NA&TRUE ha come risultato NA, invece NA&FALSE restituisce FALSE.
Supponiamo di voler visualizzare sullo schermo (print) i valori da 1 ad i, dove i varia (for) da 1 a 5.
L’istruzione che consente di creare un ciclo è “for”:
> for(i in 1:5) print(1:i)
Altri comandi analoghi sono “while” e “repeat”, i cui dettagli sono disponibili nell’help on-line.
I cicli in R, se è possibile, sono da evitare, perchè troppo dispendiosi in termini di tempo macchina.
Ad esempio, l’istruzione “sum” consente di sommare gli elementi di un vettore, che supponiamo
contenga i primi 50000 numeri naturali:
> sum(1:50000)
[1] 1250025000
Le istruzioni che seguono, consentono di pervenire allo stesso risultato, utilizzando un ciclo for, ma
in tempi più lunghi:
> x<-0
> for(i in 1:50000) x<-x+i
>x
[1] 1250025000
22
1.7 Input ed Output
1.7.1 Come salvare l’output
E’ possibile memorizzare l'output di una sessione di lavoro in un file di testo attraverso il comando
“sink”. L’output da memorizzare va specificato all’interno del comando “cat”. Supponiamo, ad
esempio di voler memorizzare la stringa “ciao” nel file di testo “prip.txt”. Le istruzioni da eseguire
sono le seguenti:
> sink("prip.txt")
> cat("ciao")
> sink()
Il comando “ sink()” serve per chiudere il file di output.
E’ possibile visualizzare il contenuto del file di output "prip.txt" dal menu:
File-Display file(s)
Le istruzioni più utilizzate per salvare l’output sono comunque “write” e “write.table”. L’istruzione
“write” memorizza il contenuto di matrici, mentre l’istruzione “write.table” consente di
memorizzare dataframe. La differenza fra una matrice e un dataframe consiste nel fatto che la
matrice è un oggetto atomico, ossia ha elementi tutti dello stesso tipo (numeri o stringhe), mentre il
dataframe contiene elementi misti.
Le istruzioni “write” e “write.table” hanno come argomenti fondamentali: l’oggetto x da inviare nel
file di output e il file di output. Ad esempio:
> x<-1:9
> write(x, file=”nome file”)
Per maggiori dettagli si può consultare l’help on-line.
Gli oggetti inviati in un file di output possono essere successivamente importati con le istruzioni di
cui si parlerà nel prossimo paragrafo.
1.7.2 Importare dati in formato testo
I principali comandi per importare dati in formato testo sono “scan” e “read.table”.
Il comando “scan” consente di importare un vettore di dati, che si può poi organizzare sotto forma
di matrice a due o più vie. Ad esempio:
> x<-scan("nome file")
> z<-matrix(x, ncol=3, byrow=TRUE)
> is.matrix(z)
> [1] TRUE
Il comando “read.table” consente di importare un dataframe.
Volendo importare un dataframe in cui la prima riga è di intestazione, al nome del file deve seguire
l’opzione “ header=TRUE ”:
> z<-read.table("nome file", header=TRUE)
> is.data.frame(z)
23
> [1] TRUE
Le colonne di un dataframe non sono direttamente accessibili; per renderle accessibili bisogna
utilizzare il comando “attach”:
> attach(z)
Vi sono dei dataset disponibili nella versione base di R, il cui elenco si può visualizzare con il
seguente comando:
> data()
Per caricare un determinato dataset, per esempio il dataset “cars”, basta specificare il suo nome
all’interno delle parentesi tonde, quindi richiamarlo:
> data(cars)
> cars
Per avere informazioni sul dataset, il comando è “help”:
> help(cars)
Il dataset “cars” è un dataframe, infatti:
> is.data.frame(cars)
[1] TRUE
1.8 Packages di R
Per conoscere l’elenco dei packages contenuti in R, il comando è:
> library()
Per avere informazioni sul contenuto di un determinato package, si utilizza la seguente istruzione:
> library(help=nome package)
Per potere essere utilizzato, un package deve essere prima caricato dal menu:
Packages-Load package
oppure richiamato con l’istruzione:
> library(nome package)
Esempio:
> library(help=nls)
> library(nls)
24
2 Statistica descrittiva con R
2.1 Immissione dei dati
2.1.1 Classificazione delle variabili
Come è noto, i dati statistici si suddividono in qualitativi e quantitativi. I dati qualitativi sono
espressi da attributi e in R vengono elegantemente rappresentati come “factor”; inoltre, se fra di essi
è possibile stabilire un ordinamento, è necessario utilizzare il comando “ordered”.
Supponiamo di aver rilevato su un gruppo di soggetti il sesso (variabile qualitativa sconnessa) e
l’età (variabile quantitativa); supponiamo che quest’ultima sia stata riportata su una scala ordinale a
tre livelli (B –bambino, G –giovane, A –anziano):
> sesso<-c("M","M","F","M","F","F","F","M")
> sesso
[1] "M" "M" "F" "M" "F" "F" "F" "M"
> str(sesso)
chr [1:8] "M" "M" "F" "M" "F" "F" "F" "M"
Il sesso viene automaticamente memorizzato come chr (character), ma il comando “factor”
rappresenta in R un modo più corretto per definire una variabile qualitativa:
> sesso<-factor(sesso)
> sesso
[1] M M F M F F F M
Levels: F M
> str(sesso)
Factor w/ 2 levels "F","M": 2 2 1 2 1 1 1 2
Se consideriamo una variabile qualitativa ordinabile, dobbiamo tener conto che R utilizza un
ordinamento alfabetico:
> età<-c("A","G","B","A","G","A","B","A")
> età
[1] "A" "G" "B" "A" "G" "A" "B" "A"
> str(età)
chr [1:8] "A" "G" "B" "A" "G" "A" "B" "A"
> età2<-factor(età)
> età2
[1] A G B A G A B A
Levels: A B G
> str(età2)
Factor w/ 3 levels "A","B","G": 1 3 2 1 3 1 2 1
Per imporre un particolare ordinamento, si può considerare l’opzione, o direttamente il comando,
“ordered”; entrambi necessitano dei livelli (levels) ordinati. Le due seguenti istruzioni sono
equivalenti:
> età2<-factor(età,levels=c("B","G","A"),ordered=TRUE)
> età2
25
[1] A G B A G A B A
Levels: B < G < A
> età3<-ordered(età,levels=c("B","G","A"))
> età3
[1] A G B A G A B A
Levels: B < G < A
Per ragioni di praticità, spesso è utile codificare le modalità di una variabile; per attribuire le
etichette ai codici si utilizza il comando "levels":
> sesso<-c(1,1,2,1,2,2,2,1)
> sesso
[1] 1 1 2 1 2 2 2 1
> sesso<-factor(sesso)
> sesso
[1] 1 1 2 1 2 2 2 1
Levels: 1 2
> levels(sesso)<-c("M","F")
> sesso
[1] M M F M F F F M
Levels: M F
Per quanto riguarda i dati quantitativi, non c’è distinzione in R fra dati quantitativi discreti e
continui. Supponiamo di aver rilevato su 8 soggetti la statura (variabile quantitativa continua):
> statura<-c(150,170,145,168,175,163,172,167)
> statura
[1] 150 170 145 168 175 163 172 167
> str(statura)
num [1:8] 150 170 145 168 175 163 172 167
R memorizza la statura come oggetto di tipo num (numeric).
Volendo essere precisi, una variabile quantitativa discreta può essere memorizzata come un oggetto
di tipo int (integer).
2.1.2 Dataset statistici
Supponiamo di aver rilevato k=4 variabili di tipologia diversa (stato civile, grado di istruzione,
numero di figli, peso) su n=25 soggetti. In R è possibile organizzare i dati statistici sotto forma di
dataset con il comando “data.frame”. Vediamo come.
x: stato civile4 - variabile qualitativa sconnessa
> x<-c(1,2,1,3,1,2,4,1,3,4,3,4,1,2,3,4,2,3,3,4,1,2,1,1,2)
> x<-factor(x)
> levels(x)<-c("N","C","V","S")
>x
[1] N C N V N C S N V S V S N C V S C V V S N C N N C
4
N: nubile/celibe, C: coniugato, V: vedovo, S: separato/divorziato
26
Levels: N C V S
y: grado di istruzione5 - variabile qualitativa ordinabile
> y<-c(1,3,1,2,1,2,4,1,3,2,3,4,1,2,3,1,2,3,3,1,4,2,1,3,2)
> y<-factor(y)
> levels(y)<-c("LE","LM","M","L")
> y<-ordered(y)
>y
[1] LE M LE LM LE LM L LE M LM M L LE LM M LE LM M M LE L LM LE M LM
Levels: LE < LM < M < L
z: n. di figli – variabile quantitativa discreta
> z<-c(0,2,1,3,0,2,4,1,3,4,3,0,1,2,3,4,2,0,3,4,1,2,1,0,2)
>z
[1] 0 2 1 3 0 2 4 1 3 4 3 0 1 2 3 4 2 0 3 4 1 2 1 0 2
w: peso – variabile quantitativa continua
>w<-c(59.20,71.20,80.10,58.89,65.12,82.14,75.20,64.00,
+ 68.23,72.10,49.00,65.63,68.14,74.30,49.51,72.14,68.25,
+ 67.14,69.00,70.80,74.34,58.15,57.23,56.22,48.00)
>w
[1] 59.20 71.20 80.10 58.89 65.12 82.14 75.20 64.00 68.23 72.10 49.00 65.63
[13] 68.14 74.30 49.51 72.14 68.25 67.14 69.00 70.80 74.34 58.15 57.23 56.22
[25] 48.00
Per facilitare l’immissione dei dati, quando questi non vengono direttamente importati da file, può
anche essere utilizzato il comando “scan()” (cfr.par. 1.2.1), che però accetta in input solo valori
numerici.
Rilevate tutte le variabili, i dati possono essere organizzati sotto forma di “dataframe” che, a
differenza di una matrice, può contenere variabili miste (cfr.par. 1.7.2):
> dataset<-data.frame(x,y,z,w)
> dataset
x yz w
1 N LE 0 59.20
2 C M 2 71.20
3 N LE 1 80.10
4 V LM 3 58.89
5 N LE 0 65.12
6 C LM 2 82.14
7 S L 4 75.20
8 N LE 1 64.00
9 V M 3 68.23
10 S LM 4 72.10
11 V M 3 49.00
5
LE: analfabeta/licenza elementare, LM: licenza media, M: maturità, L: laurea/oltre
27
12 S L 0 65.63
13 N LE 1 68.14
14 C LM 2 74.30
15 V M 3 49.51
16 S LE 4 72.14
17 C LM 2 68.25
18 V M 0 67.14
19 V M 3 69.00
20 S LE 4 70.80
21 N L 1 74.34
22 C LM 2 58.15
23 N LE 1 57.23
24 N M 0 56.22
25 C LM 2 48.00
Alle variabili può anche essere attribuito un nome nel seguente modo:
> dataset<-data.frame(X=x,Y=y,Z=z,W=w)
Una volta creato il dataframe di nome “dataset”, le singole variabili possono essere rimosse dal
workspace con il comando “rm” (cfr.par. 1.4.2):
> rm(x,y,z,w)
E’ ovviamente utile salvare (save) il dataset creato, affinché possa essere ricaricato (load) in un
secondo momento (cfr.par. 1.4.2):
> save(dataset,file="nome file")
> load("nome file")
E’ stato già detto che le colonne di un dataframe non sono direttamente accessibili (cfr.par. 1.7.2).
Per poter utilizzare una variabile, è necessario far seguire al nome del dataframe il nome della
variabile preceduto dal dollaro:
> dataset$Y
se, invece, si vogliono rendere disponibili tutte le variabili del dataset, si può utilizzare il seguente
comando:
> attach(dataset)
la cui funzione contraria è:
> detach(dataset)
La funzione “attach” consente anche di richiamare un dataframe salvato su un file e poi rimosso dal
workspace, senza caricarlo in memoria:
> attach("nome file")
28
In questo caso, se utilizziamo il comando “ls()”, vedremo che il workspace non conterrà il
dataframe “dataset”.
Il comando “detach()” chiude l’accesso al dataframe “dataset”.
Poiché un dataframe è comunque una matrice, anche se non contiene dati tutti dello stesso tipo, è
possibile estrarre da esso righe e colonne. Ad esempio, se si vuole estrarre dal dataframe “dataset”
la quarta riga, il comando è:
> dataset[4,]
2.2 Serie di dati e distribuzioni di frequenza
2.2.1 Distribuzioni di frequenza per valori singoli
Se abbiamo salvato il dataframe di nome “dataset” in un file di nome “prova.rda”, possiamo
richiamarlo col seguente comando:
> attach("prova.rda")
e rendere accessibili le variabili col comando:
> attach(dataset).
Costruiamo adesso le distribuzioni di frequenza delle variabili X, Y, Z. L’istruzione è “table”:
> table(X)
X
NCVS
8665
> table(Y)
Y
LE LM M L
8 7 7 3
> table(Z)
Z
01234
55654
Per calcolare le frequenze relative, basta dividere per il totale delle osservazioni, ossia per la
lunghezza (length) di ciascun vettore:
> table(X)/length(X)
X
N C V S
0.32 0.24 0.24 0.20
> table(Y)/length(Y)
Y
LE LM M L
0.32 0.28 0.28 0.12
> table(Z)/length(Z)
29
Z
0 1 2 3 4
0.20 0.20 0.24 0.20 0.16
per calcolare le frequenze relative percentuali, basta moltiplicare le frequenze relative per 100:
> table(X)/length(X)*100
X
N C V S
32 24 24 20
> table(Y)/length(Y)*100
Y
LE LM M L
32 28 28 12
> table(Z)/length(Z)*100
Z
0 1 2 3 4
20 20 24 20 16
Per calcolare le frequenze cumulate, utilizziamo il comando “cumsum”. Ovviamente, ha un senso
calcolare le frequenze cumulate solo a partire da una variabile qualitativa ordinabile. Calcoliamo,
dunque, le frequenze cumulate assolute, relative e percentuali per le variabili Y e Z:
> cumsum(table(Y))
LE LM M L
8 15 22 25
> cumsum(table(Y)/length(Y))
LE LM M L
0.32 0.60 0.88 1.00
> cumsum(table(Y)/length(Y)*100)
LE LM M L
32 60 88 100
> cumsum(table(Z))
0 1 2 3 4
5 10 16 21 25
> cumsum(table(Z)/length(Z))
0 1 2 3 4
0.20 0.40 0.64 0.84 1.00
> cumsum(table(Z)/length(Z)*100)
0 1 2 3 4
20 40 64 84 100
2.2.2 Distribuzioni di frequenza per classi di valori
La variabile W (peso) è una variabile quantitativa continua, per cui, in questo caso, è opportuno
costruire una distribuzione di frequenza per classi. A tal fine, R dispone di due comandi: ”cut” ed
“hist”.
Il comando “cut” ha come argomento fondamentale “breaks”, in cui bisogna specificare gli estremi
delle classi o il numero delle classi. Ovviamente, prima di scegliere gli estremi delle classi, occorre
ordinare i dati. L’ordinamento degli elementi di un vettore è possibile in R con il comando “sort”:
30
>W
[1] 59.20 71.20 80.10 58.89 65.12 82.14 75.20 64.00 68.23 72.10 49.00 65.63
[13] 68.14 74.30 49.51 72.14 68.25 67.14 69.00 70.80 74.34 58.15 57.23 56.22
[25] 48.00
> sort(W)
[1] 48.00 49.00 49.51 56.22 57.23 58.15 58.89 59.20 64.00 65.12 65.63 67.14
[13] 68.14 68.23 68.25 69.00 70.80 71.20 72.10 72.14 74.30 74.34 75.20 80.10
[25] 82.14
> e<-c(45,55,65,75,85)
> dati<-cut(W,breaks=e)
> dati
[1] (55,65] (65,75] (75,85] (55,65] (65,75] (75,85] (75,85] (55,65] (65,75]
[10] (65,75] (45,55] (65,75] (65,75] (65,75] (45,55] (65,75] (65,75] (65,75]
[19] (65,75] (65,75] (65,75] (55,65] (55,65] (55,65] (45,55]
Levels: (45,55] (55,65] (65,75] (75,85]
Per default R costruisce classi chiuse a destra, altrimenti bisogna aggiungere l’opzione
“right=FALSE”:
> dati<-cut(W,breaks=e, right=FALSE)
> dati
[1] [55,65) [65,75) [75,85) [55,65) [65,75) [75,85) [75,85) [55,65) [65,75)
[10] [65,75) [45,55) [65,75) [65,75) [65,75) [45,55) [65,75) [65,75) [65,75)
[19] [65,75) [65,75) [65,75) [55,65) [55,65) [55,65) [45,55)
Levels: [45,55) [55,65) [65,75) [75,85)
Il comando "cut" crea un oggetto di tipo "factor", cioè è come se trasformasse la variabile da
quantitativa in qualitativa, perché ad ogni dato associa la classe cui appartiene, che costituisce un
livello:
> str(dati)
Factor w/ 4 levels "[45,55)","[55,65)",..: 2 3 4 2 3 4 4 2 3 3 ...
Per cui, per costruire una distribuzione di frequenza (per classi), è possibile adesso utilizzare il
comando “table”:
> table(dati)
dati
[45,55) [55,65) [65,75) [75,85)
3
6
13
3
Un’altra istruzione che consente di determinare una distribuzione di frequenza per classi è “hist”. Il
secondo argomento è “breaks”, la cui funzione è analoga a quella già vista per il comando “cut”; se
non si vuole costruire un’istogramma, è necessaria anche l’opzione “plot=FALSE”:
> hist(W,e,plot=FALSE)
$breaks
[1] 45 55 65 75 85
$counts
31
[1] 3 6 13 3
$intensities
[1] 0.01200000 0.02400000 0.05200000 0.01200000
$density
[1] 0.01200000 0.02400000 0.05200000 0.01200000
$mids
[1] 50 60 70 80
$xname
[1] "W"
$equidist
[1] TRUE
attr(,"class")
[1] "histogram"
Il comando “hist” crea un oggetto con struttura di lista, dove: i “breaks” sono gli estremi delle
classi; i “counts” le frequenze assolute, le “intensities o density” le densità di frequenza6, i “mids” i
valori centrali delle classi; “xname” il nome della variabile ed “equidist” una variabile logica, che
vale TRUE se le classi hanno ampiezza costante. L’oggetto creato da “hist” appartiene alla classe
“histogram”.
2.3 Rappresentazioni grafiche
2.3.1 Grafico a colonne
Il grafico a colonne, come è noto, è tipico delle variabili qualitative. Se la variabile qualitativa è
ordinabile va, ovviamente, precedentemente ordinata. Il comando che consente di rappresentare un
grafico a colonne è “plot”. Il comando “plot” ha una serie di argomenti, i cui dettagli sono
disponibili consultando l’help on-line. Ad esempio, è possibile attribuire un’etichetta ai due assi
cartesiani (xlab e ylab), inserire un titolo (main) e un sottotitolo (sub), scegliere il colore (col) e così
via:
> help(plot)
> plot(X, xlab="stato civile", ylab="frequenze assolute", main="grafico a colonne", sub="fonte:....",
col="red")
6
4
2
0
frequenze assolute
8
grafico a colonne
N
6
C
V
S
stato civile
fonte:....
Le densità di frequenza vengono calcolate da R come rapporto fra le frequenze relative e le ampiezze delle classi
32
E’ possibile rappresentare, in ordinata, le frequenze relative; l’istruzione è:
> plot(table(X)/length(X), lwd=50)
L’opzione “lwd” consente di modificare la larghezza delle colonne.
2.3.2
Grafico a torta
Anche il grafico a torta è tipico delle variabili qualitative, quando il numero delle modalità non è
troppo elevato. Il comando è “pie”:
> pie(table(X), col=c(2,3,4,7), main="grafico a torta")
grafico a torta
N
C
S
V
> pie(table(X), density=c(3,5,10,15), main="grafico a torta")
Le opzioni “col” e “density” consentono, rispettivamente, di scegliere il colore o lo spessore del
tratteggio dei settori.
2.3.3
Diagramma cartesiano
Il diagramma cartesiano è tipico delle variabili quantitative discrete, quale è Z. Il comando è:
3
2
1
0
table(Z)
4
5
6
> plot(table(Z))
0
1
2
3
4
Z
33
2.3.4 Istogramma e poligono di frequenza
L’istogramma è la rappresentazione grafica tipica di una variabile quantitativa continua, quale è W.
All’istogramma viene in genere sovrapposto il poligono di frequenza, che come è noto, è una
spezzata che passa per i punti medi delle basi superiori dei rettangoli.
L’istruzione per rappresentare un istogramma è “hist”, già utilizzata per la costruzione di una
distribuzione di frequenza per classi:
> e<-c(45,50,65,70,85)
> hist(W, e)
0.02
0.00
Density
0.04
Histogram of W
50
60
70
80
W
Come si può notare, R rappresenta, giustamente, in ordinata le densità di frequenza, quando le classi
scelte non hanno, come in questo caso, tutte la stessa ampiezza. Se, erroneamente, si vogliono
rappresentare in ordinata le frequenze assolute, bisogna aggiungere l’opzione “freq=TRUE”:
> hist(W,e,freq=TRUE)
Per default R costruisce classi di ampiezza uguale, secondo i criteri di alcuni statistici (consultare
l’help on-line), riportando in ordinata frequenze assolute. In questo caso, infatti, la base agisce solo
come fattore di scala. Per avere in ordinata densità di frequenza si può aggiungere l'opzione
“freq=FALSE”. Si noti come il numero delle classi per R è un suggerimento e non un ordine:
> op<-par(mfrow=c(2,2))
> hist(W,main="Sturges")
> hist(W,breaks="Scott",main="Scott")
> hist(W,breaks="FD",main="Freedman-Diaconis")
> hist(W,breaks=7,main="7 classi")
> par(op)
34
Scott
50
60
70
4
0
Frequency
0 2 4 6
Frequency
8
Sturges
80
40
60
80
W
Freedman-Diaconis
7 classi
40
60
0 2 4 6
Frequency
4
0
Frequency
8
W
80
W
50
60
70
80
W
Le istruzioni
> op<-par(mfrow=c(2,2))
> par(op)
consentono, rispettivamente, di aprire e chiudere una finestra grafica suddivisa in sottofinestre,
secondo le indicazioni dell’opzione “mfrow” (in questo caso le sottofinestre sono 2×2). In tal modo,
è possibile rappresentare più grafici in un’unica finestra.
Volendo sovrapporre un poligono di frequenza ad un istogramma, potremmo costruire la seguente
funzione:
pf<-function(x, e)
{
if(missing(e))
ist<-hist(x)
else
ist<-hist(x,breaks=e)
xc<-ist$mids
xe<-ist$breaks
e1<-min(xe)-(min(xc)-min(xe))
e2<-max(xe)+(max(xe)-max(xc))
n<-ist$counts
d<-ist$intensities
if(ist$equidist)
lines(c(e1, xc, e2), c(0, n, 0))
else
lines(c(e1, xc, e2), c(0, d, 0))
}
Analizziamo la funzione creata nei dettagli.
35
“pf” è funzione di “x” e di “e”, vettori che contengono, rispettivamente, i valori della variabile
rilevata e gli estremi delle classi. Il primo test (if) verifica se “e” è stato omesso (missing); in tal
caso, R sceglierà per noi il numero, quindi gli estremi, delle classi. Il secondo test verifica se le
classi hanno tutte la stessa ampiezza (if(ist$equidist)); in tal caso, verranno riportate in ordinata le
frequenze assolute, viceversa saranno considerate le densità di frequenza.
Il comando “lines” traccia, su un grafico preesistente, segmenti fra punti, dunque richiede in input
due vettori che contengono le coordinate dei punti. Gli oggetti “xc, xe, e1, e2, n, d” definiscono le
coordinate di tali punti. Ricordiamo che “ist” è un oggetto di classe “hist” ed ha struttura di lista, di
cui “ist$mids, ist$breaks, ist$counts, ist$intensities, ist$equidist“ sono elementi.
I comandi “min” e “max” consentono di determinare, rispettivamente, il valore minimo e il valore
massimo di un vettore.
Per costruire un poligono di frequenza non resta, dunque, che richiamare la funzione “pf”. Vediamo
alcuni esempi:
op<-par(mfrow=c(2,2))
pf(W)
pf(W,"Scott")
pf(W,"FD")
pf(W,5)
par(op)
e<-c(45,50,65,70,85)
pf(W,e)
0.02
0.00
Density
0.04
Histogram of x
50
60
70
80
x
Un comando utile per costruire un poligono di frequenza è anche “polygon”, di cui parleremo più
avanti (cfr. par. 4.5.1).
2.3.5 Funzione di ripartizione
Il package “stats” di R contiene la funzione “ecdf”, che consente di rappresentare la f.r. (funzione di
ripartizione) nel caso discreto:
> library()
> library(help=stats)
> library(stats)
> str(ecdf)
function (x)
36
Tracciamo il grafico della f.r. per Z, che avrà un andamento a gradini, essendo Z una variabile
quantitativa discreta. Il comando è:
> plot(ecdf(Z), xlab="z", ylab="F(z)", main="funzione di ripartizione")
0.6
0.4
0.0
0.2
F(z)
0.8
1.0
funzione di ripartizione
0
1
2
3
4
z
Per calcolare il valore della f.r. in un punto, ad esempio per calcolare F(2.5), utilizziamo il
comando:
> ecdf(Z)(2.5)
[1] 0.64
Infatti, calcolando le frequenze relative cumulate:
> cumsum(table(Z)/length(Z))
0 1 2 3 4
0.20 0.40 0.64 0.84 1.00
risulta:
F(z) = 0
F(z) = 0.20
F(z) = 0.40
F(z) = 0.64
F(z) = 0.84
F(z) = 1
x<0
0 ≤ x<1
1 ≤ x<2
2 ≤ x<3
3 ≤ x<4
x≥4
Se X è una variabile quantitativa continua, la f.r. assumerà la forma di una spezzata. In particolare:
F(x) = 0
F(x) = Fi
F(x) = 1
x ≤ x1
x = xi+1
x > xn
37
dove x1 e xn sono, rispettivamente, l’estremo inferiore della prima classe e l’estremo superiore
dell’ultima classe. Tra xi e xi+1 la f.r. coincide col segmento passante per i punti [xi,Fi-1] e [xi+1,Fi].
Volendo costruire, dunque un programmino, per rappresentare la f.r. di W, che è una variabile
quantitativa continua, possiamo procedere come segue. Ordiniamo innanzitutto il vettore W:
> sort(W)
[1] 48.00 49.00 49.51 56.22 57.23 58.15 58.89 59.20 64.00 65.12 65.63 67.14
[13] 68.14 68.23 68.25 69.00 70.80 71.20 72.10 72.14 74.30 74.34 75.20 80.10
[25] 82.14
Scegliamo come estremi delle classi i seguenti valori:
> e<-c(45,55,65,75,85)
Per comodità inseriamo un valore più piccolo di 45 e un valore più grande di 85:
> e<-c(35,45,55,65,75,85,95)
Costruiamo la distribuzione di frequenza per classi:
> dati<-cut(W,breaks=e)
> dati
[1] (55,65] (65,75] (75,85] (55,65] (65,75] (75,85] (75,85] (55,65] (65,75]
[10] (65,75] (45,55] (65,75] (65,75] (65,75] (45,55] (65,75] (65,75] (65,75]
[19] (65,75] (65,75] (65,75] (55,65] (55,65] (55,65] (45,55]
Levels: (35,45] (45,55] (55,65] (65,75] (75,85] (85,95]
> table(dati)
dati
(35,45] (45,55] (55,65] (65,75] (75,85] (85,95]
0
3
6
13
3
0
La distribuzione delle frequenze relative cumulate è:
> Fi<-cumsum(table(dati)/length(dati))
> Fi
(35,45] (45,55] (55,65] (65,75] (75,85] (85,95]
0.00 0.12 0.36 0.88 1.00 1.00
Aggiungiamo ad Fi uno zero, poiché la f.r. inizialmente vale proprio 0:
> Fi<-c(0,Fi)
> Fi
(35,45] (45,55] (55,65] (65,75] (75,85] (85,95]
0.00 0.00 0.12 0.36 0.88 1.00 1.00
Utilizziamo il comando “plot”, già utilizzato in altre occasioni, per rappresentare questa volta
coppie di punti.
In particolare, vogliamo rappresentare le coppie di punti (xi, Fi-1), contenute nei vettori ordinati “e”
ed “Fi”:
38
> plot(e, Fi, type="b", xlab="w", ylab="F(w)", main="funzione di ripartizione")
0.6
0.4
0.0
0.2
F(w)
0.8
1.0
funzione di ripartizione
40
50
60
70
80
90
w
L’opzione type="b" consente di congiungere i punti con un segmento, creando una spezzata.
2.3.6 Boxplot
Il boxplot è costituito da una scatola, i cui estremi sono il I ed il III quartile (Q1, Q3), sezionata
dalla mediana (Q2), avente dei baffi in corrispondenza dei valori minimo e massimo. In presenza di
outliers (valori anomali), che per R sono quei valori che stanno al di fuori dell’intervallo [Q1-1.5DI,
Q3+1.5DI]7, i baffi vengono posti in corrispondenza delle osservazioni più vicine agli estremi di
tale intervallo e interne ad esso.
Gli outliers vengono evidenziati da R con dei puntini.
Il boxplot dà indicazioni sulla simmetria o asimmetria di una distribuzione. Dal boxplot della
variabile W sembrerebbe che la distribuzione è asimmetrica negativamente, in quanto (Q3Q2)<(Q2-Q1), e non presenta outliers. Tuttavia bisogna ricordare che per una distribuzione
simmetrica è (Q3-Q2)=(Q2-Q1), ma non è detto il contrario (condizione necessaria, ma non
sufficiente).
50
55
60
65
70
75
80
> boxplot(W)
7
DI=Q3-Q1 è la differenza interquartile
39
2.4 Indici di sintesi
2.4.1 Le medie
I QUANTILI
In R è possibile calcolare i quantili con il comando “quantile”; in particolare, per la mediana esiste
un comando specifico, che è “median”. Questi comandi, però, sono validi solo su dati numerici.
Consideriamo nuovamente le variabili del dataframe “dataset”; ricordiamo che ha senso calcolare i
quantili a partire da una variabile qualitativa ordinabile:
> median(Y)
Error in median(Y) : need numeric data
> median(Z)
[1] 2
> median(W)
[1] 68.14
Come si può notare, R dà errore per la variabile Y, poiché questa non è espressa da numeri. Si può
ovviare a questo inconveniente calcolando i quantili sulla variabile inizialmente codificata, facendo
attenzione ai casi di indeterminazione. Ad esempio, supponiamo di aver rilevato le seguenti
modalità (già ordinate) su 10 soggetti:
Licenza elementare, Licenza elementare, Licenza media, Licenza media, Licenza media, Maturità,
Maturità, Maturità, Maturità, Laurea.
Codificando la variabile, si ha:
> x<-c(1,1,2,2,2,3,3,3,3,4)
> median(x)
[1] 2.5
ma, in questo caso, la mediana non può essere data dalla semisomma dei due valori centrali.
Il comando “quantile” vuole anch’esso, come primo argomento, un vettore di numeri e ne
restituisce il valore minimo, i tre quartili (o ciò che è lo stesso il 25°, il 50° e il 75° percentile) e il
valore massimo:
> quantile(Z)
0% 25% 50% 75% 100%
0 1 2 3 4
> quantile(W)
0% 25% 50% 75% 100%
48.00 58.89 68.14 72.10 82.14
E’ possibile far calcolare ad R quantili particolari; in tal caso, è necessario inserire, come secondo
argomento, un vettore di numeri compresi tra 0 ed 1. Se, ad esempio, vogliamo calcolare il 10° e il
90° percentile di Z e W, i comandi sono:
40
> quantile(Z, c(.10,.90))
10% 90%
0 4
> quantile(W, c(.10,.90))
10% 90%
52.194 74.856
LE MEDIE POTENZIATE DI ORDINE R
Fra le medie potenziate di ordine r:
⎛ x
Mr= ⎜⎜ ∑
⎝ i =1 n
n
r
i
⎞
⎟
⎟
⎠
1
r
r = -1 media armonica
r = 0 media geometrica
r = 1 media aritmetica
r = 2 media quadratica
r = 3 media cubica
sussiste, come è noto, la seguente relazione:
M-1≤M0≤M1≤M2≤M3
Una funzione generica per poterle calcolare è la seguente:
mr<-function(x, r)
{
n<-length(x)
sum((x^r)/n)^(1/r)
}
Due semplici funzioni per poter calcolare, rispettivamente, la media armonica e la media
geometrica sono:
#media armonica
mean.a<-function(x)
{
length(x)/sum(1/x)
}
# media geometrica
mean.g<-function(x)
{
prod(x)^(1/length(x))
}
I comandi “sum” e “prod” sommano e moltiplicano, rispettivamente, gli elementi di un vettore.
41
In R esiste il comando “mean”, che consente di calcolare direttamente la media aritmetica.
Facciamo degli esempi:
> mr(W,1)
[1] 65.7612
> mean(W)
[1] 65.7612
Il comando “weighted.mean” consente di calcolare la media aritmetica ponderata; in tal caso, è
necessario specificare il vettore dei pesi.
Il comando “summary”, consente di ottenere il minimo, Q1, Q2, la media aritmetica, Q3 e il
massimo di un vettore numerico:
> summary(W)
Min. 1st Qu. Median Mean 3rd Qu. Max.
48.00 58.89 68.14 65.76 72.10 82.14
Lo stesso comando, applicato ad un dataframe, restituisce gli stessi indici di sintesi per tutte le
variabili numeriche, mentre per le variabili espresse da attributi fornisce l’unica sintesi possibile,
ossia la distribuzione di frequenza:
> summary(dataset)
X
Y
Z
N:8 LE:8 Min. :0.00
C:6 LM:7 1st Qu.:1.00
V:6 M :7 Median :2.00
S:5 L :3 Mean :1.92
3rd Qu.:3.00
Max. :4.00
W
Min. :48.00
1st Qu.:58.89
Median :68.14
Mean :65.76
3rd Qu.:72.10
Max. :82.14
2.4.2 Gli indici di etererogeneità
Come è noto, per una variabile qualitativa si parla più propriamente di eterogeneità, piuttosto che di
variabilità.
Un indice di eterogeneità è quello proposto da Gini:
k
G = 1 − ∑ fi2
i =1
che in R si può calcolare costruendo la seguente funzione:
gini<-function(x) {
n<-length(x)
f<-table(x)/n
k<-length(f)
if(k==1)
return(0)
1-sum(f^2)
}
42
Tale indice restituisce (return) 0, se (if) il numero k delle modalità della variabile è pari a 1
(massima omogeneità). Se, invece, il totale delle frequenze n è equiripartito fra le k modalità
(massima eterogeneità), l’indice assumerà il valore massimo (k-1)/k.
Rapportando G a (k-1)/k, dunque, si ottiene un indice di eterogeneità relativo, che varia tra 0 ed 1:
ginirel<-function(x) {
n<-length(x)
f<-table(x)/n
k<-length(f)
if(k==1)
return(0)
g<-1-sum(f^2)
g*k/(k-1)
}
Una funzione equivalente a “ginirel”, e che tiene conto della funzione “gini” già costruita, è:
ginirel2<-function(x,k) {
gini(x)*k/(k-1)
}
esempi:
> gini(X)
[1] 0.7424
> ginirel(X)
[1] 0.9898667
> ginirel2(X,4)
[1] 0.9898667
> gini(Y)
[1] 0.7264
> ginirel(Y)
[1] 0.9685333
> ginirel2(Y,4)
[1] 0.9685333
2.4.3 Gli indici di variabilità
Gli indici di eterogeneità si possono calcolare ovviamente anche per variabili quantitative, anche se
per quest’ultime esistono degli indici più informativi come, ad esempio, lo scarto quadratico medio.
Volendo calcolare l’intervallo di variazione, l’istruzione “range” restituisce il minimo e il massimo
di un vettore numerico:
> range(W)
[1] 48.00 82.14
> min(W)
[1] 48
> max(W)
[1] 82.14
43
Il range, però, non tiene conto dei valori centrali di una serie ordinata.
Lo scarto quadratico medio si può calcolare come radice (sqrt) della varianza, la cui istruzione in R
è:
> var(W)
[1] 85.48671
oppure con il comando “sd”, che sta per “standard deviation”.
I comandi “var” ed “sd” restituiscono gli indici campionari; bisogna dunque moltiplicarlarli per (n1)/n o per la radice di tale rapporto per ottenere, rispettivamente, la varianza e la deviazione
standard della popolazione:
> n<-length(W)
> var(W)*(n-1)/n
[1] 82.06724
Un’alternativa è costruire una funzione apposita:
varianza<-function(x)
{
m<-mean(x)
n<-length(x)
sum((x-m)^2)/n
}
varianza2<-function(x)
{
m<-mean(x)
n<-length(x)
sum(x^2)/n-m^2
}
La funzione “varianza2” calcola la varianza con la formula ridotta.
Esempi:
> varianza(W)
[1] 82.06724
> varianza2(W)
[1] 82.06724
Volendo calcolare un indice di variabilità relativa, ad esempio il coefficiente di variazione, che
consente di confrontare la variabilità di due variabili rilevate con diversa unità di misura o aventi
ordine medio di grandezza diverso, si può utilizzare la seguente funzione:
CV<-function(x)
{
m<-mean(x)
sqrt(varianza(x))/abs(m)
}
44
> CV(W)
[1] 0.1377575
2.4.4 Indici di asimmetria e curtosi
Supponiamo di aver rilevato la statura e il peso su un gruppo di soggetti:
> peso<-c(45,45,76,48,70,60,90,85,90,49.5,45,85,60,60,70,78,66,77,61,56,48,53,67,71,62,50,75)
>statura<-c(160,165,165,161,183,160,186,186,174,160,165,177,170,170,168,181,172,180,177,165,
+160,172,169,178,169,162,170)
Creiamo un dataframe di nome ‘’quest’’ :
40
60
80
100
120
140
160
180
> quest<-data.frame(X=peso,Y=statura)
> attach(quest)
> boxplot(X,Y,names=c("peso","statura"))
statura
peso
Come si può notare, è possibile comparare boxplot relativi a più variabili, inserendoli in un’unica
finestra. L’opzione “names” consente di attribuire un etichetta a ciascun boxplot.
I boxplot danno indicazioni sulla simmetria/asimmetria di una distribuzione, basandosi sulla
differenza tra quartili. Un indice di asimmetria più informativo è dato da:
β =
1
µ3
σ3
che è possibile calcolare con la seguente funzione:
beta1<-function(x) {
n<-length(x)
s3<-sqrt(var(x)*(n-1)/n)^3
mx<-mean(x)
m3<-sum((x-mx)^3)/n
m3/s3
}
45
L’indice β1 calcolato sul peso e sulla statura conferma quanto già si evince dai boxplot e cioè
un’asimmetria positiva per entrambe le variabili:
> beta1(X)
[1] 0.2386716
> beta1(Y)
[1] 0.386686
Una funzione che consente di valutare la curtosi, tenendo conto dell’indice
β2 =
µ4
,
σ4
è la seguente:
beta2<-function(x) {
n<-length(x)
s4<-sqrt(var(x)*(n-1)/n)^4
mx<-mean(x)
m4<-sum((x-mx)^4)/n
m4/s4
}
esempi:
> beta2(X)
[1] 1.956912
> beta2(Y)
[1] 2.087023
46
3 Relazioni tra variabili
3.1 L’analisi delle tabelle di contingenza
Supponiamo di aver rilevato, in una classe di 28 studenti universitari, due variabili: il sesso (x) e la
scuola di provenienza (y). Per facilitare l’immissione dei dati, le modalità di ciascuna variabile sono
state così codificate:
sesso
Femmina
Maschio
1
2
scuola di provenienza
Liceo classico (LC)
Liceo scientifico (LS)
Ist. Tecnico commerciale (ITC)
Ist. Tecnico Industriale (ITI)
Ist. Tecnico per geometri (ITG)
Altro (A)
1
2
3
4
5
6
> x<-c(1,1,1,1,2,1,2,2,2,1,1,2,1,1,2,2,2,2,2,1,1,1,2,2,1,1,2,1)
> y<-c(2,2,3,2,2,2,2,7,6,2,2,5,2,2,3,7,3,2,2,1,2,3,3,6,2,3,3,3)
Essendo x e y due variabili qualitative, dobbiamo memorizzarle come “factor”, quindi possiamo
attribuire i livelli ai codici:
> x<-factor(x)
> levels(x)<-c("F","M")
> y<-factor(y)
> levels(y)<-c("LC","LS","ITC","ITI","ITG","A")
Il comando per costruire una distribuzione di frequenza congiunta è “table”, già incontrato per
costruire la distribuzione di frequenza di una variabile singola. In questo caso, “table” ha come
argomento entrambe le variabili in esame:
> tab1<-table(x,y)
> tab1
y
x LC LS ITC ITI ITG A
F 1 10 4 0 0 0
M 0 4 4 1 22
“tab1” è un oggetto di classe “table”:
> class(tab1)
[1] "table"
47
Per conoscere il totale generale n dei soggetti su cui sono state rilevate le due variabili, basta
applicare il comando “sum” all’oggetto “table”:
> sum(tab1)
[1] 28
mentre “dim” informa sul numero di righe e colonne della tabella:
> dim(tab1)
[1] 2 6
Il comando “dimnames” consente di conoscere le modalità delle due variabili:
> dimnames(tab1)
$x
[1] "F" "M"
$y
[1] "LC" "LS" "ITC" "ITI" "ITG" "A"
Attraverso la seguente istruzione, invece, si può risalire al nome delle due variabili:
> names(dimnames(tab1))
[1] "x" "y"
Supponiamo di disporre già di una tabella doppia di frequenza.
Si consideri, ad esempio, la distribuzione dei laureati del 1991 per gruppo di corso di laurea e
condizione occupazionale nel 1993:
X\Y
Medicina
Economia
Lettere
Occupato
stabilmente
681
732
770
Occupato
precariamente
466
72
585
Disoccupato
118
18
147
La tabella sopra può essere memorizzata in R attraverso il comando “matrix”, già noto:
> vett<-c(681,466,118,732,72,18,770,585,147)
> tab2<-matrix(vett,3,3,byrow=TRUE)
> tab2
[,1] [,2] [,3]
[1,] 681 466 118
[2,] 732 72 18
[3,] 770 585 147
Le modalità delle due variabili, X (laurea) ed Y (occupazione), si possono inserire attraverso i
comandi “rownames” e “colnames”:
> rownames(tab2)<-c("Medicina","Economia","Lettere")
> colnames(tab2)<-c("Occupato stab.","Occupato prec.","Disoccupato")
> tab2
48
Occupato stab. Occupato prec. Disoccupato
Medicina
681
466
118
Economia
732
72
18
Lettere
770
585
147
> sum(tab2) # totale generale
[1] 3589
> dim(tab2) # n. righe e colonne
[1] 3 3
Essendo “tab2” un oggetto di tipo “matrix”, è possibile estrarre righe e colonne (cfr.par.1.4.1), che
rappresentano, rispettivamente, le distribuzioni condizionate di Y rispetto a X e di X rispetto a Y:
> tab2[1,]
Occupato stab. Occupato prec. Disoccupato
681
466
118
> tab2[2,]
Occupato stab. Occupato prec. Disoccupato
732
72
18
> tab2[3,]
Occupato stab. Occupato prec. Disoccupato
770
585
147
> tab2[,1]
Medicina Economia Lettere
681 732 770
> tab2[,2]
Medicina Economia Lettere
466
72 585
> tab2[,3]
Medicina Economia Lettere
118
18 147
E’ possibile con R individuare anche le distribuzioni marginali di X e di Y, attraverso il comando
“margin.table”:
> margin.table(tab2,1)
Medicina Economia Lettere
1265 822 1502
> margin.table(tab2,2)
Occupato stab. Occupato prec. Disoccupato
2183
1123
283
E’ infatti:
> sum(tab2[1,])
[1] 1265
> sum(tab2[2,])
[1] 822
> sum(tab2[3,])
[1] 1502
49
> sum(tab2[,1])
[1] 2183
> sum(tab2[,2])
[1] 1123
> sum(tab2[,3])
[1] 283
Le distribuzioni relative condizionate possono essere determinate con il comando “prop.table”:
> prop.table(tab2,1)
Occupato stab. Occupato prec. Disoccupato
Medicina 0.5383399 0.36837945 0.09328063
Economia 0.8905109 0.08759124 0.02189781
Lettere
0.5126498 0.38948069 0.09786951
> prop.table(tab2,2)
Occupato stab. Occupato prec. Disoccupato
Medicina 0.3119560 0.41495993 0.41696113
Economia 0.3353184 0.06411398 0.06360424
Lettere
0.3527256 0.52092609 0.51943463
Infatti:
> # frequenze relative rispetto ai totali di riga
> tabr<-tab2
> tabr[1,]<-tab2[1,]/sum(tab2[1,])
> tabr[2,]<-tab2[2,]/sum(tab2[2,])
> tabr[3,]<-tab2[3,]/sum(tab2[3,])
> tabr
Occupato stab. Occupato prec. Disoccupato
Medicina 0.5383399 0.36837945 0.09328063
Economia 0.8905109 0.08759124 0.02189781
Lettere
0.5126498 0.38948069 0.09786951
> print.table(tabr,digits=2)
Occupato stab. Occupato prec. Disoccupato
Medicina
0.54
0.368
0.093
Economia
0.89
0.088
0.022
Lettere
0.51
0.389
0.098
> # frequenze relative rispetto ai totali di colonna
> tabc<-tab2
> tabc[,1]<-tab2[,1]/sum(tab2[,1])
> tabc[,2]<-tab2[,2]/sum(tab2[,2])
> tabc[,3]<-tab2[,3]/sum(tab2[,3])
> tabc
Occupato stab. Occupato prec. Disoccupato
Medicina 0.3119560 0.41495993 0.41696113
Economia 0.3353184 0.06411398 0.06360424
Lettere
0.3527256 0.52092609 0.51943463
> print.table(tabc,digits=2)
Occupato stab. Occupato prec. Disoccupato
50
Medicina
Economia
Lettere
0.31
0.34
0.35
0.415
0.417
0.064
0.064
0.521
0.519
Il comando “print.table” serve a visualizzare una tabella, mentre l’opzione “digits” stabilisce il
numero di cifre decimali significative dopo la virgola.
La distribuzione relativa rispetto al totale generale si può così determinare:
> prop.table(tab2)
Occupato stab. Occupato prec. Disoccupato
Medicina 0.1897464 0.1298412 0.032878239
Economia 0.2039565 0.0200613 0.005015325
Lettere
0.2145444 0.1629980 0.040958484
infatti:
> tabt<-tab2/sum(tab2)
> tabt
Occupato stab. Occupato prec. Disoccupato
Medicina 0.1897464 0.1298412 0.032878239
Economia 0.2039565 0.0200613 0.005015325
Lettere
0.2145444 0.1629980 0.040958484
> tabt<-tab2/sum(tab2)
dove, ovviamente, è:
> sum(tabt)
[1] 1
INDICI DI ASSOCIAZIONE
E’ noto che se le distribuzioni relative condizionate sono tutte uguali fra di loro, si parla di
“indipendenza in distribuzione” fra le due variabili. In tal caso, le frequenze congiunte osservate
sono uguali alle frequenze teoriche di indipendenza:
nij = nij*, dove nij* = ni.×n.j/n
L’indice X = ∑∑
2
i
j
(n
ij
− nij*
nij*
)
2
di Pearson, basandosi sulla differenza fra frequenze osservate e
frequenze teoriche, consente di verificare se fra due variabili c’è indipendenza in distribuzione.
Il comando “summary”, applicato ad un oggetto di classe “table”, calcola, fra le altre cose, anche
l’indice X2 (Chisq):
> summary(tab1)
Number of cases in table: 28
Number of factors: 2
Test for independence of all factors:
Chisq = 8.472, df = 5, p-value = 0.1321
Chi-squared approximation may be incorrect
51
Il comando “summary”, applicato all’oggetto “tab2”, non restituisce X2, non avendo questi classe
“table”. L’oggetto “tab2” può però essere trasformato in un oggetto di classe “table” con il comando
“as.table”:
> ntab<-as.table(tab2)
> summary(ntab)
Number of cases in table: 3589
Number of factors: 2
Test for independence of all factors:
Chisq = 358.4, df = 4, p-value = 2.691e-76
L’oggetto che restituisce l’istruzione “summary” ha la struttura di una lista, per cui il valore di X2
può essere estratto e rapportato al suo valore massimo (maxX2=nmin[(r-1),(c-1)]), in modo da
ottenere un indice normalizzato:
> ris<-summary(tab1)
> str(ris)
List of 7
$ n.vars : int 2
$ n.cases : int 28
$ statistic: num 8.47
$ parameter: num 5
$ approx.ok: logi FALSE
$ p.value : num 0.132
$ call : NULL
- attr(*, "class")= chr "summary.table"
> ris$statistic
[1] 8.471795
L’indice X2 si può calcolare anche con il comando “chisq.test”:
> chisq.test(tab2)
3.2 La regressione lineare semplice
Su un campione di 81 docenti americani è stato rilevato il reddito annuo (in dollari), l’età e gli anni
di servizio.
I dati sono riportati nel file "regr.txt". Si vuole stabilire se esiste una relazione fra le prime due
variabili ed individuare la funzione che rappresenti al meglio tale relazione. Inoltre, si vuole
verificare, inoltre, attraverso l’uso di un indice appropriato, se la suddetta funzione si adatta bene ai
dati osservati.
Importiamo i dati con l’istruzione “read.table” e rendiamo accessibili le colonne del dataframe:
> z<-read.table("regr.txt", header=TRUE)
> attach(z)
Attribuiamo la variabile “reddito” (variabile dipendente) all’oggetto “y” e la variabile “età”
(variabile indipendente) all’oggetto “x”:
> y<-reddito
52
> x<-eta
Rappresentiamo graficamente (scatterplot) le coppie di punti (x,y), utilizzando il comando “plot”,
già visto in precedenza (cfr.par.2.3.5):
> plot(x,y,xlab="età",ylab="reddito",main="grafico
lineare")
reddito-età",sub="regressione
semplice
30000
20000
reddito
40000
grafico reddito-età
30
40
50
60
età
regressione semplice lineare
Dall’andamento della nuvola di punti sembrerebbe che fra le due variabili sussista una relazione di
tipo lineare. Proviamo, dunque, ad adattare una retta, stimandone i parametri con il metodo dei
minimi quadrati:
yˆ = αˆ + βˆ x,
αˆ = M y − βˆM x
βˆ =
σ xy
σ x2
Occorre calcolare le due medie Mx ed My, la varianza σx2 per la variabile “età” e la covarianza fra le
n
due variabili σ xy =
∑ (x
i =1
i
− M x )( y i − M y )
n
= M xy − M x M y :
> mx<-mean(x)
> mx
[1] 45.62963
> my<-mean(y)
> my
[1] 30027.51
> n<-length(x)
>n
[1] 81
> varx<-(sum((x-mx)^2))/n
> varx
[1] 90.48011
> covxy<-sum((x-mx)*(y-my))/n
> covxy
[1] 46402.82
La varianza e la covarianza possono essere calcolate anche con le formule ridotte:
53
> varx<-sum(x^2)/n-mx^2
> varx
[1] 90.48011
> covxy<-sum(x*y)/n-mx*my
> covxy
[1] 46402.82
oppure, rispettivamente, con le funzioni “var” e “cov”, già presenti in R; bisogna tener presente,
però, che i comandi “var” e “cov” dividono la devianza e la codevianza per “n-1” e non per “n”:
> varx<-var(x)*(n-1)/n
> varx
[1] 90.48011
> covxy<-cov(x,y)*(n-1)/n
> covxy
[1] 46402.82
Le stime dei due parametri sono:
> b<-covxy/varx
>b
[1] 512.851
> a<-my-b*mx
>a
[1] 6626.304
La retta di regressione può essere rappresentata su un grafico preesistente, lo scatterplot in questo
caso, con il comando “abline”, che vuole in input le stime dei due parametri:
> abline(a,b)
30000
20000
reddito
40000
grafico reddito-età
30
40
50
60
età
regressione semplice lineare
Un indice di bontà di adattamento della retta ai dati osservati è il coefficiente di determinazione
devreg
devres
= 1−
che, come è noto, è uguale al quadrato del coefficiente di correlazione
R2 =
2
nο y
nο y2
lineare r =
σ xy
.
σ xσ y
54
Occorre, dunque, calcolare dapprima gli scarti quadratici medi σx (sx) e σy (sy) delle due variabili:
> sx<-sqrt(varx)
> sx
[1] 9.512103
> vary<-var(y)*(n-1)/n
> vary
[1] 37268494
> sy<-sqrt(vary)
> sy
[1] 6104.793
> r<-covxy/(sx*sy)
>r
[1] 0.7990922
> R2<-r^2
> R2
[1] 0.6385483
Esiste, comunque, in R il comando “cor”, che consente di calcolare direttamente il coefficiente r:
> r<-cor(x,y)
>r
[1] 0.7990922
Volendo calcolare R2 tramite la devianza di regressione (devreg) o tramite la devianza residua
(devres), si può procedere nel seguente modo:
> ystim<-a+b*x# valori stimati
> res<-y-ystim# residui
> devres<-sum(res^2)
> devy<-n*vary
> R2<-1-devres/devy
> R2
[1] 0.6385483
>
> devreg<-sum((ystim-my)^2)
> R2<-devreg/devy
> R2
[1] 0.6385483
Molto semplicemente, per condurre una completa analisi di regressione, si può utilizzare il
comando “summary” che ha come argomento un oggetto prodotto dal comando “lm”. Il comando
“lm” richiede in input la variabile dipendente (y) e la variabile indipendente (x), separati da una
tilde (alt+126), e restituisce le stime dei parametri di regressione:
> retta<-lm(y~x)
> retta
Call:
lm(formula = y ~ x)
Coefficients:
(Intercept)
x
55
6626.3
512.9
> summary(retta)
Call:
lm(formula = y ~ x)
Residuals:
Min
1Q Median
3Q Max
-8340.20 -2719.05 -84.43 2891.00 9400.59
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 6626.30 2023.44 3.275 0.00157 **
x
512.85 43.41 11.814 < 2e-16 ***
--Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1
Residual standard error: 3716 on 79 degrees of freedom
Multiple R-Squared: 0.6385, Adjusted R-squared: 0.634
F-statistic: 139.6 on 1 and 79 DF, p-value: < 2.2e-16
Per calcolare i valori stimati, si può anche far uso del comando "predict", che però richiede come
secondo argomento un oggetto di tipo "data.frame", anche per predire un solo valore:
> ystim<-predict(retta,data.frame(x))
> predict(retta,data.frame(x=27))
[1] 20473.28
> predict(retta,data.frame(x=c(27,62)))
1
2
20473.28 38423.07
opzioni grafico
Poiché l’oggetto che restituisce il comando “lm” contiene le stime dei due parametri, questi può
essere inserito come primo argomento nel comando “abline”:
> plot(x,y,xlab="età",ylab="reddito",main="grafico reddito-età")
> abline(retta,lty=3,lwd=5,col="red")
> text(40,40000,"la retta di regressione")
> text(40,38000,expression(y[i]==hat(beta)[0]+hat(beta)[1]*x))
40000
grafico reddito-età
la retta di regressione
^ +β
^ x
y=β
0
1
30000
25000
20000
reddito
35000
i
56
30
40
50
età
60
Gli argomenti “lty”, “lwd” e “col” definiscono, rispettivamente, il tipo di tratteggio, lo spessore e il
colore del tratto.
Il comando “text” aggiunge testi e notazioni a grafici preesistenti; vuole in input le coordinate del
punto in cui inserire il testo, quindi il testo. Il comando “expression”, all’interno di “text”, consente
di scrivere formule e simboli matematici, il cui elenco si può visionare consultando l’help di
“plotmath”:
> help(plotmath)
A volte si rende necessario ampliare o ridurre il range di ciascun asse cartesiano. All’interno del
comando “plot” ciò è possibile con le opzioni “xlim” e “ylim”, che per default considerano l’intero
range dei due vettori in input (in questo caso x e y):
30000
50000
y
30000
10000
20000
25000
y
35000
70000
40000
> op<-par(mfrow=c(1,2))
> plot(x,y,xlim=range(x),ylim=range(y))
> plot(x,y,xlim=c(10,100),ylim=c(10000,80000))
> par(op)
30
40
50
x
60
20 40 60 80
x
E’ possibile costruire a proprio piacimento gli assi. In tal caso, aggiungere
l’opzione ‘’axes=FALSE’’ all’interno del comando ‘’plot’’ e utilizzare i comandi ‘’axis(1)’’ e
‘’axis(2)’’ per costruire, rispettivamente, l’asse X e l’asse Y. Gli altri argomenti di “axis” sono due
vettori: il primo visualizza delle tacche sull’asse, il secondo visualizza dei valori in corrispondenza
delle tacche tracciate. Il comando “expression”, già incontrato all’interno del comando “text”, e qui
inserito all’interno del comando “axis”, consente di visualizzare un’espressione in corrispondenza
di una determinata coordinata, in questo caso Mx prima ed My poi. Il comando ‘’box()’’, infine,
racchiude il grafico in un riquadro:
> plot(x,y,axes=FALSE)
> sequenzax<-seq(20,70,10)
> axis(1,c(mx,sequenzax),c(expression(bar(x)),sequenzax))
> sequenzay<-seq(19000,45000,5000)
> axis(2,c(my,sequenzay),c(expression(bar(y)),sequenzay))
> box()
57
44000
39000
34000
yi = 6626.304 + 512.851xi
19000
24000
y
29000
y
(xn, yn)
30
40
x
50
60
x
Volendo tracciare dei segmenti paralleli ai due assi, che si incontrano nel punto di coordinate (Mx,
My) si può procedere nel seguente modo:
> lines(c(mx,mx,0),c(0,my,my),lty=3)
> text(46,31000,expression((list(bar(x)[n],bar(y)[n]))))
> points(mx,my,pch=4,cex=3,col="red")
Il comando “points”, che è l’unico non ancora analizzato, consente di evidenziare determinati punti
su un grafico preesistente. Le opzioni “pch” e “cex” consentono di scegliere, rispettivamente, il tipo
di simbolo e la sua dimensione. I seguenti comandi tracceranno la retta e definiranno la sua
espressione:
> abline(retta,col="yellow",lwd=2)
> text(40,38000,expression(y[i]==6626.304+512.851*x[i]))
Val la pena, infine, di provare la seguente istruzione, che restituisce n.4 grafici utili per l’analisi dei
residui:
> plot(retta)
3.3 La dipendenza in media: il rapporto di correlazione
data(chickwts); z<-chickwts; attach(z); x<-feed; y<-weight
e<-seq(100,450,50)
y2<-cut(y,breaks=e)
tab<-table(x,y2)
xt<-margin.table(tab,1); yt<-margin.table(tab,2)
yc<-hist(y,plot=FALSE)$mids
mc<-numeric()
for (i in 1:6) mc[i]<-weighted.mean(yc,tab[i,]) # mc: contiene le medie condizionate di Y|X
varmc<-weighted.mean(mc^2,xt)-(weighted.mean(mc,xt))^2
vary<-weighted.mean(yc^2,yt)-(weighted.mean(yc,yt))^2
eta2<-varmc/vary
58
MODULO 2
59
4 Calcolo delle probabilità con R
4.1 Esperimenti casuali
Consideriamo il lancio di un dado regolare. Lo spazio campionario Ω ha cardinalità card(Ω)=6 ed è
costituito dai seguenti eventi elementari: Ω = {1, 2, 3, 4, 5, 6}.
Attribuiamo tali eventi ad un oggetto:
> dado<-1:6
> dado
[1] 1 2 3 4 5 6
Il comando “sample” consente di simulare n prove di un esperimento casuale, ad esempio, n lanci di
un dado regolare. Ha come argomenti: Ω, n, l’opzione “replace” che, se posta uguale a “TRUE”,
consente di replicare lo stesso risultato:
> sample(dado,6)
[1] 5 3 1 2 6 4
> sample(dado,20)
Error in sample(length(x), size, replace, prob) :
can't take a sample larger than the population
when replace = FALSE
> sample(dado,20,replace=TRUE)
[1] 5 5 5 6 2 3 2 2 5 1 6 4 4 5 4 1 3 5 5 5
Il secondo comando dà, ovviamente, errore, in quanto n supera card(Ω) e l’opzione di default
“replace = FALSE” non prende in considerazione risultati già ottenuti.
4.2 Calcolo combinatorio
Per calcolare le permutazioni semplici di n oggetti Pn=n!, si può utilizzare il comando “prod”. Il
fattoriale dei primi 7 numeri naturali, ad esempio, si ottiene con il seguente comando:
> prod(1:7)
[1] 5040
E’ noto che fra il fattoriale di un numero e la funzione gamma esiste la seguente relazione:
n! = Γ(n+1),
per cui un comando equivalente al precedente è:
> gamma(8)
[1] 5040
Se si vuole calcolare il logaritmo (log) di una gamma è possibile utilizzare direttamente la funzione
“lgamma”, per cui i seguenti comandi sono equivalenti:
> log(gamma(8))
[1] 8.525161
> lgamma(8)
60
[1] 8.525161
Ovviamente, se consideriamo la funzione inversa (exp), ritorniamo al risultato precedente:
> exp(lgamma(8))
[1] 5040
Per n>170, non è possibile lavorare con i fattoriali. Eseguiamo, allora, i calcoli in scala logaritmica,
ma utilizzando la funzione “lgamma”:
> prod(1:171)
[1] Inf
> gamma(172)
[1] Inf
> log(gamma(172))
[1] Inf
> lgamma(172)
[1] 711.7147
⎛ n⎞
n!
Per calcolare il numero delle combinazioni semplici C n ,k = ⎜⎜ ⎟⎟ =
di n oggetti distinti di
⎝ k ⎠ k!(n − k )!
classe k (coefficiente binomiale), si può utilizzare il comando “choose”, che richiede, nell’ordine, n
e k. Ad esempio:
> choose(5,3)
[1] 10
4.3 Valore atteso e varianza di variabili casuali
Se X ed Y sono due variabili casuali, con funzione di distribuzione di probabilità, rispettivamente,
p(x) e p(y), ed a e b sono due costanti, è noto che:
E(a)=a
var(a)=0
E(aX)=a E(X)
var(aX)=a2var(X)
E(aX +bY)=aE(X)+bE(Y)
var(aX+bY)=a2var(X)+b2var(Y)+2abcov(X,Y)
dove:
E(X)=Σxp(x)
var(X)=Σ[x-E(X)]2p(x)=E(X2)-[E(X)]2
E(X2)=Σx2p(x)
E(Y)=Σyp(y)
var(Y)=Σ[y-E(Y)]2p(y)=E(Y2)-[E(Y)]2
E(Y2)=Σy2p(y)
cov(X,Y)= ΣΣ[x-E(X)][x-E(X)]p(x,y)=E(XY)-E(X)E(Y)
E(XY)= ΣΣxyp(x,y)
Se X e Y sono indipendenti, p(x,y)= p(x)p(y), allora cov(X,Y)=0.
61
esempio
Sia P0 il prezzo di un titolo a inizio di un anno solare e P il prezzo dello stesso titolo a fine anno. Il
suo rendimento R sarà:
R=(P-P0)/P0;
si vuole calcolare il rendimento atteso e la varianza:
E(R)=(E(P)-P0)/P0
var(R)=var(P)/P02
Supponiamo nota la distribuzione di probabilità (pr) della variabile casuale P (p), il valore atteso
(EP) e la varianza (varP) di P saranno :
> p<-c(21,23.5,26,32,43)
> pr<-c(0.1,0.25,0.3,0.25,0.1)
> EP<-sum(p*pr)
> EP
[1] 28.075
> varP<-sum(((p-EP)^2)*pr)
> varP
[1] 37.65687
Se il prezzo iniziale del titolo (P0) è pari a 20 euro, il rendimento medio (ER) e la varianza (varR)
saranno:
> P0<-20
> ER<-(EP-P0)/P0
> ER
[1] 0.40375
> varR<-varP/P0^2
> varR
[1] 0.09414219
E‘ noto che un modo per ridurre il rischio di un investimento consiste nella diversificazione del
portafoglio, ossia nell‘acquisto di un insieme di attività finanziarie (titoli, azioni, fondi) con
caratteristiche differenti. L‘obiettivo è quello di massimizzare il rendimento atteso, minimizzando
nello stesso tempo il rischio. A tal fine viene assegnato a ciascun investimento un coefficiente di
ponderazione, che corrisponde alla quota del portafoglio destinata a quella particolare attività.
Supponiamo di aver scelto due attività; il rendimento Rp del portafoglio sarà:
Rp=aRx+bRy, dove a+b=1.
Supponiamo che per ciascuno dei due investimenti sono stati stimati i rendimenti Rx e Ry (per ogni
1000$ di capitale investito), sotto 3 diverse condizioni economiche (recessione, stabilità,
espansione), cui sono associate le seguenti probabilità di verificarsi:
62
Rx / Ry
-100
100
250
tot
-200
0,2
50
350
0,5
0,2
0,5
0,3
0,3
tot
0,2
0,5
0,3
1
Costruiamo con R la distribuzione di probabilità congiunta e determiniamo le distribuzioni di
probabilità marginali:
> Rx<-c(-100,100,250)
> Ry<-c(-200,50,350)
> pRxRy<-matrix(rep(0,9),3,3)
> pRxRy[1,1]<-0.2
> pRxRy[2,2]<-0.5
> pRxRy[3,3]<-0.3
> rownames(pRxRy)<-Rx
> colnames(pRxRy)<-Ry
> pRxRy
-200 50 350
-100 0.2 0.0 0.0
100 0.0 0.5 0.0
250 0.0 0.0 0.3
> sum(pRxRy)
[1] 1
> margin.table(pRxRy,1)
-100 100 250
0.2 0.5 0.3
> margin.table(pRxRy,2)
-200 50 350
0.2 0.5 0.3
Per determinare E(Rp) e var(Rp), costruiamo la seguente funzione, che calcola il valore atteso e la
varianza di una combinazione lineare di variabili casuali:
> mvcl<-function (a, x, y, pxy) {
+ px <- margin.table(pxy,1)
+ py <- margin.table(pxy,2)
+ mx <- sum(x * px)
+ my <- sum(y * py)
+ vx <- sum((x - mx)^2 * px)
+ vy <- sum((y - my)^2 * py)
+ cxy <-sum(x%*%t(y)*pxy)-mx*my
+ # oppure (cfr.par.boh)
+ # cxy <-sum(x%o%y*pxy)-mx*my
+ mr <- a * mx + (1 - a) * my
+ vr <- a^2 * vx + (1 - a)^2 * vy + 2 * a * (1 - a) * cxy
+ return(list(ER = mr, VR = vr))
+}
63
La funzione “mvcl” vuole in input il coefficiente di ponderazione, le due variabili casuali e la
distribuzione di probabilità congiunta. Il comando “return” restituisce una lista (list) di oggetti, nel
nostro caso il valore atteso e la varianza della combinazione lineare, cui è stato dato il nome “ER” e
“VR”.
Se supponiamo di voler formare un portafoglio destinando a ciascun investimento la stessa quota
del totale a=b=1-a=0.5, E(Rp) e var(Rp) saranno:
> a<-0.5
> ris<-mvcl(a,Rx,Ry,pRxRy)
> ris
$ER
[1] 97.5
$VR
[1] 24806.25
Notiamo che il rischio di portafoglio sarà più elevato del rendimento atteso, infatti è:
> sqrt(ris$VR)
[1] 157.5
Se a è un vettore, la funzione “mvcl” restituirà una lista che ha come elementi dei vettori:
> a<-seq(0,1,0.1)
>a
[1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
> ris<-mvcl(a,Rx,Ry,pRxRy)
> ris
$ER
[1] 90.0 91.5 93.0 94.5 96.0 97.5 99.0 100.5 102.0 103.5 105.0
$VR
[1] 37900.00 35040.25 32301.00 29682.25 27184.00 24806.25 22549.00 20412.25
[9] 18396.00 16500.25 14725.00
I seguenti grafici mostrano il rendimento atteso al variare di a, considerando diverse opzioni per
“type”:
> par(mfrow=c(3,2))
> plot(a,ris$ER,ylab="E(Rp)",main="rendimento medio",type="p")
> plot(a,ris$ER,ylab="E(Rp)",main="rendimento medio",type="h")
> plot(a,ris$ER,ylab="E(Rp)",main="rendimento medio",type="b")
> plot(a,ris$ER,ylab="E(Rp)",main="rendimento medio",type="c")
> plot(a,ris$ER,ylab="E(Rp)",main="rendimento medio",type="o")
> plot(a,ris$ER,ylab="E(Rp)",main="rendimento medio",type="l")
64
E(Rp)
0.2
0.4
0.6
0.8
1.0
0.0
0.6
0.8
rendimento medio
1.0
E(Rp)
0.2
0.4
0.6
0.8
90 95
105
rendimento medio
90 95
1.0
0.0
0.2
0.4
0.6
0.8
a
rendimento medio
rendimento medio
1.0
90 95
E(Rp)
105
a
0.0
0.2
0.4
0.6
0.8
1.0
90 95
E(Rp)
0.4
a
105
0.0
E(Rp)
0.2
a
105
0.0
90 95
90 95
E(Rp)
105
rendimento medio
105
rendimento medio
0.0
0.2
0.4
0.6
a
0.8
1.0
a
E’ interessante anche vedere come varia la varianza al variare di a:
> par(mfrow=c(1,2))
> plot(a,ris$ER,ylab="E(Rp)",main="rendimento medio",type="b")
> plot(a,ris$VR,ylab="var(Rp)",main="varianza del rendimento",type="b")
varianza del rendimento
90
25000
15000
20000
95
E(Rp)
var(Rp)
100
30000
35000
105
rendimento medio
0.0
0.4
0.8
0.0
a
0.4
0.8
a
4.4 Variabili casuali discrete
4.4.1 v.c. binomiale
La variabile casuale binomiale ha, come è noto, funzione di distribuzione di probabilità:
⎛ n⎞
p( x) = P( X = x) = ⎜⎜ ⎟⎟ p x (1 − p) n − x
⎝ x⎠
x= 0, 1, 2, …, n
E(X)=np
var(X)=np(1-p)
Supponiamo che X ~ Bin(n=7,p=0.4). Si vogliono calcolare le seguenti probabilità:
65
- p(4)=P(X=4)
- F(4)=P(X≤4)
- P(X>4)=1- P(X≤4)=1-F(4)
Le probabilità puntuali si calcolano in R premettendo il suffisso ‘’d’’ al nome della variabile,
mentre il valore della funzione di ripartizione in un punto si calcola premettendo il suffisso ‘’p’’:
> dbinom(4,7,0.4)
[1] 0.193536
> pbinom(4,7,0.4)
[1] 0.903744
> pbinom(4,7,0.4,lower.tail=FALSE)
[1] 0.096256
I comandi “dbinom” e “pbinom” vogliono in input: il valore x, n e p. L’opzione
“lower.tail=FALSE”, come si è visto, è servita a calcolare probabilità complementari.
Volendo calcolare i quantili q di una variabile, è necessario premettere al nome della variabile il
suffisso “q”.
Ad esempio, rappresentiamo graficamente la v.c. X ~ Bin(n=10, p=0.5). Ricorriamo al comando
“plot”, già noto, scegliendo l’opzione type=”h”. Per calcolare le probabilità puntuali utilizziamo il
comando “dbinom”:
0.00 0.05 0.10 0.15 0.20 0.25
px
> x<-0:10
> px<-dbinom(x,10,0.5)
> plot(x,px,type="h")
0
2
4
6
8
10
x
Come ci aspetteremmo, è:
> qbinom(0.5,10,0.5)
[1] 5
Il comando per calcolare i quantili vuole in input dapprima il valore di α, dove α= P(X≤ q), quindi i
parametri della distribuzione in esame.
4.4.2 v.c. bernoulliana
La variabile casuale bernoulliana ha funzione di distribuzione di probabilità:
66
p( x) = P( X = x) = p x (1 − p)1− x
x= 0, 1
E(X)=p
var(X)=p(1-p)
Sappiamo che X ~ Ber(p) ~Bin(n=1,p).
Supponiamo che X ~ Ber(p=0.7). Si vogliono calcolare le seguenti probabilità:
- p(1)=P(X=1)
- F(0)=P(X≤0)
Possiamo utilizzare gli stessi comandi utilizzati in precedenza, dando ad n valore 1:
> dbinom(1,1,0.7)
[1] 0.7
> pbinom(0,1,0.7)
[1] 0.3
4.4.3 v.c. geometrica
La variabile casuale geometrica o di Pascal8, ha funzione di distribuzione di probabilità:
p ( x) = P ( X = x) = p(1 − p ) x
x= 0, 1, 2, …
E(X)=(1-p)/p
var(X)=(1-p)/p2
Rappresentiamo graficamente la v.c. X ~ Geom(p=1/7):
0.08
0.04
px
0.12
> x<-0:10
> px<-dgeom(x,1/7)
> plot(x, px, type="h")
0
2
4
6
8
10
x
Se vogliamo che tutti i valori di X considerati vengano rappresentati, costruiamo noi gli assi,
aggiungendo in “plot” l’opzione “ axes=FALSE ” e ricorrendo al comando “axis”:
> plot(x, px, type="h", axes=FALSE)
> axis(1,x)
NULL
> axis(2)
NULL
> box()
8
v.c. “tempo di attesa (in termini di numero di insuccessi) prima di ottenere il I successo”
67
0.12
0.08
0.04
px
0
1
2
3
4
5
6
7
8
9
10
x
Ricordiamo che la v.c. geometrica gode di un’importante proprietà: la mancanza di memoria.
Osservati t insuccessi, la probabilità di aspettare ancora s insuccessi prima del I successo è:
P(X ≥ t+s| X ≥ t)=P(X ≥ s)
4.4.4 v.c. binomiale negativa
La variabile casuale binomiale negativa9, ha funzione di distribuzione di probabilità:
⎛ x + n − 1⎞ n
⎟⎟ p (1 − p) x
p ( x) = P( X = x) = ⎜⎜
⎠
⎝x
E(X)=n(1-p)/p
x= 0, 1, 2, …
n=1,2,...
var(X)=n(1-p)/p2
Supponiamo che X ~ BinNeg(n=3, p=0.4). Si vogliono calcolare le seguenti probabilità:
- P(X=2)
- P(X≤2)
- P(X>2)
Il comando è ‘’nbinom’’, cui si premette il suffisso opportuno:
> dnbinom(2,3,0.4)
[1] 0.13824
> pnbinom(2,3,0.4)
[1] 0.31744
> pnbinom(2,3,0.4,lower.tail=FALSE)
[1] 0.68256
Ovviamente X ~ Geom(p) ~ BinNeg(n=1, p).
Infatti, ad esempio, per X=4 e p=0.4, si ha:
> dgeom(4,0.4)
[1] 0.05184
> dnbinom(4,1,0.4)
9
v.c. “tempo di attesa (in termini di numero di insuccessi) per ottenere l’n-mo successo”
68
[1] 0.05184
4.4.5 v.c. ipergeometrica
La variabile casuale ipergeometrica ha funzione di distribuzione di probabilità:
⎛ N − K ⎞⎛ K ⎞
⎜⎜
⎟⎟⎜⎜ ⎟⎟
⎝ n − x ⎠⎝ x ⎠
p ( x) = P ( X = x) =
⎛N⎞
⎜⎜ ⎟⎟
⎝n ⎠
E(X)=np
con
var(X)=np(1-p)
max(0,n-(N-K)) ≤ x≤min(n,K)
N −n
.
N −1
Supponiamo che X ~ Iperg(N=100,K=30,n=10). Si vogliono calcolare le seguenti probabilità:
- P(X=3)
- P(X≤ 3)
I comandi sono, rispettivamente, i seguenti :
> dhyper(3,30,70,10)
[1] 0.2811634
> phyper(3,30,70,10)
[1] 0.65402
Come si può notare, i suddetti comandi richiedono in input, dopo il valore di X, K, N-K ed n.
4.4.6 v.c. di Poisson
La variabile casuale di Poisson ha funzione di distribuzione di probabilità:
p ( x) = P ( X = x) =
µ x e −µ
x!
x= 0, 1, 2, …
E(X)=var(X)=µ
Supponiamo che X ~ Poi(µ=7). Si vogliono calcolare le seguenti probabilità:
- P(X=3)
- P(X≤3)
Le istruzioni sono le seguenti:
> dpois(3,7)
[1] 0.05212925
> ppois(3,7)
[1] 0.08176542
69
E’ noto che la distribuzione di Poisson si ottiene come distribuzione limite della distribuzione
binomiale, quando n→∞ e p→0 con la stessa velocità, in modo tale che µ=np si mantenga costante.
La v.c. di Poisson descrive perciò eventi rari, con probabilità di successo molto basse.
Rappresentiamola graficamente:
0.00
0.05
px
0.10
0.15
> x<-0:25
> px<-dpois(x,7)
> plot(x,px,type="h")
0
5
10
15
20
25
x
La v.c. di Poisson si presta bene anche a descrivere il numero di realizzazioni di un evento aleatorio
in un determinato intervallo di tempo. Supponiamo, ad esempio, che il numero medio di telefonate
ad un centralino sia di 15 per ora (µ=15). Calcoliamo:
- la prob. che in 10 min. non arrivino chiamate;
- la prob. che in 30 min. si abbiano al più 8 chiamate
> dpois(0,15/60*10)
[1] 0.082085
> ppois(30,15/60*8)
[1] 1
4.5 Variabili casuali continue
4.5.1 v.c. normale o di Gauss
La variabile casuale normale ha funzione di densità di probabilità:
f ( x) =
1
σ 2π
−
e
( x − µ )2
2σ 2
-∞< x <∞
µ>0
σ>0
E(X)=µ
var(X)=σ2
E’ noto che per una v.c. continua è P(X=x)=0. In tal caso, il prefisso “d” al nome della variabile
serve a calcolare il valore della funzione nel punto x.
Le istruzioni per determinare la densità, la funzione di ripartizione e i quantili della gaussiana sono:
> dnorm(x, µ,σ)
> pnorm(x, µ,σ)
> qnorm(α, µ,σ)
70
I valori di default di µ e σ sono, rispettivamente, 0 e 1, quindi, se omettiamo tali parametri, R
calcolerà la densità, la funzione di ripartizione e i quantili della normale standard f(z), con
X −µ
Z=
:
σ
> dnorm(z)
> pnorm(z)
> qnorm(α)
Per rappresentare graficamente una funzione, possiamo utilizzare il comando “curve”, seguito dal
nome della funzione e dal range di X sul quale si vuole rappresentare la funzione.
Rappresentiamo graficamente una normale standard:
0.2
0.0
0.1
dnorm(x)
0.3
0.4
> curve(dnorm(x),-4,4)
-4
-2
0
2
4
x
Volendo rappresentare più funzioni nello stesso grafico, bisogna riutilizzare il comando “curve”,
aggiungendo l’opzione “add=TRUE”. Le opzioni xlab="", ylab="", invece, servono ad eliminare le
etichette agli assi.
Rappresentiamo due curve normali con diversa media e uguale varianza:
0.00 0.02 0.04 0.06 0.08 0.10 0.12
> curve(dnorm(x),-4,4)
> curve(dnorm(x,5,3),-10,30,ylab="")
> curve(dnorm(x,15,3),-10,30,add=TRUE)
> axis(1,c(5,15),c(expression(mu==5),expression(mu==15)))
> abline(v=5)
> abline(v=15)
-10
0
µ=5
10
µ = 15
20
30
x
71
Il comando “abline”, già incontrato, nell’ambito della regressione, per tracciare una retta generica
nel piano, consente qui di tracciare due rette parallele all’asse y, in corrispondenza dei valori di µ. A
tal fine, basta specificare l’opzione “v=costante”. Viceversa, se si vuole tracciare una retta parallela
all’asse x, bisogna specificare l’opzione “h=costante”.
Rappresentiamo adesso due curve normali con uguale media, ma diversa varianza:
0.15
σ=3
0.00
0.05
σ=2
0.10
0.20
> curve(dnorm(x,5,3),-10,20,ylim=c(0,0.2),ylab="")
> curve(dnorm(x,5,2),-10,20,add=TRUE)
> text(10,0.15,expression(sigma==2))
> text(10,0.10,expression(sigma==3))
-10
-5
0
5
10
15
20
x
Le opzioni “ylim” e “lty” all’interno del comando “curve” hanno la stessa funzione incontrata per
altri comandi, ossia definiscono, rispettivamente, il range dell’asse Y e il tipo di tratteggio:
0.10
0.15
0.20
> curve(dnorm(x,5,3),-10,20,ylim=c(0,0.2),ylab="",lty=3)
> curve(dnorm(x,5,2),-10,20,add=TRUE,lty=5)
> legend(10,0.10,c(expression(sigma==3),expression(sigma==2)),lty=c(3,5))
0.00
0.05
σ=3
σ=2
-10
-5
0
5
10
15
20
x
Il comando “legend” consente di inserire una legenda all’interno di un grafico. Vuole in input: le
coordinate del punto in cui si vuole inserire la legenda, un vettore di caratteri alfanumerici (qui è
stato usato il comando “expression” per inserire espressioni), un vettore di colori (col) o di simboli
(pch) o di diversi tratteggi (lty), come in questo caso.
Per maggiori dettagli sull’uso di questo comando, si rimanda all’help on-line.
Vediamo adesso come è possibile evidenziare una parte di area sottesa da una curva.
72
I comandi che seguono sono tutti noti, tranne “polygon”, che consente di unire punti, formando
appunto un poligono. Il comando “polygon” ha come argomenti: due vettori contenenti le
coordinate dei punti, la densità e l’angolazione del tratteggio all’interno del poligono, oppure il
colore.
Tratteggiamo, ad esempio, le code di una curva normale standard; in particolare, tratteggiamo le
aree in corrispondenza dei valori di z interni agli intervalli (-∞,-1], [1,+∞):
> curve(dnorm(x),-3,3,axes=FALSE,ylab="",xlab="",ylim=c(0,.5))
> axis(1,c(-3,-1,0,1,3),c("","-z",0,"z",""))
> # coda sinistra
> cod<-seq(-3,-1,length=100)
> x<-c(-3,cod,-1,-3)
> y<-c(0,dnorm(cod),0,0)
> polygon(x,y,20,45)
> # coda destra
> cod<-seq(1,3,length=100)
> x<-c(1,cod,3,1)
> y<-c(0,dnorm(cod),0,0)
> polygon(x,y,20,45)
> abline(h=0)
> text(0,.47,expression(F(-z)==1-F(z)))
> lines(c(0,0),c(0,dnorm(0)))
> box()
F(− z) = 1 − F(z)
-z
0
z
Coloriamo ora l’area sottesa da una curva normale standard, in corrispondenza dei valori di z interni
all’intervallo [-1, 1]:
> curve(dnorm(x),-3,3,axes=FALSE,ylab="",xlab="z",ylim=c(0,.5))
> axis(1,c(-3,-1,0,1,3),c("","-1",0,"1",""))
> vals<-seq(-1,1,length=100)
> x<-c(-1,vals,1,-1)
> y<-c(0,dnorm(vals),0,0)
> polygon(x,y,col="red")
> abline(h=0)
> text(0,.47,expression(P(-1<Z<1)))
> box()
73
P(-1<Z<1)
-1
0
1
z
Supponiamo adesso che X ~ N(5,3). Calcoliamo le seguenti probabilità, a tutti note:
- P(µ-σ<X<µ+σ) ~ P(-1<Z<1)
- P(µ-2σ<X<µ+2σ) ~ P(-2<Z<2)
- P(µ-3σ<X<µ+3σ) ~ P(-3<Z<3)
> m<-5
> s<-sqrt(3)
> pnorm(m+s,m,s)-pnorm(m-s,m,s)
[1] 0.6826895
> pnorm(1)-pnorm(-1)
[1] 0.6826895
> pnorm(m+2*s,m,s)-pnorm(m-2*s,m,s)
[1] 0.9544997
> pnorm(2)-pnorm(-2)
[1] 0.9544997
> pnorm(m+3*s,m,s)-pnorm(m-3*s,m,s)
[1] 0.9973002
> pnorm(3)-pnorm(-3)
[1] 0.9973002
Il quantile in corrispondenza di α=0.5 sarà ovviamente µ:
> qnorm(.5,m,s)
[1] 5
> qnorm(.5)
[1] 0
4.5.2 v.c. uniforme
La variabile casuale uniforme ha funzione di densità di probabilità:
1
f ( x) =
b−a
a+b
E( X ) =
2
a≤ x ≤ b
74
2
(
b − a)
var( X ) =
12
Le istruzioni per determinare la densità, la funzione di ripartizione e i quantili della v.c. uniforme
sono:
> dunif(x, a, b)
> punif(x, a, b)
> qunif(α, a, b)
Rappresentiamo graficamente la v.c.
corrispondenza di α=0.5:
X ~ U(a=2, b=5), calcoliamo F(3.5) e il quantile in
> curve(dunif(x,2,5),0,7,ylim=c(0,.8))
> punif(3.5,2,5)
[1] 0.5
> qunif(0.5,2,5)
[1] 3.5
4.5.3 v.c. chi-quadrato
La variabile casuale Chi-quadrato ha funzione di densità di probabilità:
1
f ( x) =
n
2
2 Γ(n / 2)
x n / 2 −1e − x / 2
x≥ 0
E(X)=n
var(X)=2n
La funzione gamma
∞
Γ(a)= ∫ x α −1 e − x dx
0
gode, come è noto, della seguente proprietà:
Γ(a+1)= aΓ(a)
con a∈R+
Ricordiamo anche che:
Γ(1/2)= π :
> gamma(1/2)
[1] 1.772454
> sqrt(pi)
[1] 1.772454
E’ noto che se Xi i.i.d. N(µ ,σ2), allora ΣiZ i 2 ~χ 2(n), dove Z i =
Xi − µ
σ
.
Le istruzioni per determinare la densità, la funzione di ripartizione e i quantili della v.c. Chiquadrato sono:
> dchisq(x, n)
> pchisq(x, n)
75
> qchisq(α, n)
Rappresentiamo graficamente una v.c. X ~χ 2(n); la v.c. X è asimmetrica positivamente e tenderà
alla gaussiana al crescere dei gradi di libertà (n→∞):
0.15 0.20 0.25
> curve(dchisq(x,3),0,20,ylab="")
> curve(dchisq(x,5),0,20,add=TRUE,lty=2)
> curve(dchisq(x,7),0,20,add=TRUE,lty=3)
> curve(dchisq(x,9),0,20,add=TRUE,lty=5)
> legend(10,0.2,c("n=3","n=5","n=7","n=9"),lty=c(1,2,3,5))
0.00 0.05 0.10
n=3
n=5
n=7
n=9
0
5
10
15
20
x
4.5.4 v.c. t di Student
La variabile casuale t di Student ha funzione di densità di probabilità:
x2 ⎞
Γ((n + 1) / 2) ⎛
⎜⎜1 +
⎟
f ( x) =
n ⎟⎠
πnΓ(n / 2) ⎝
se n>2
− ( n +1) / 2
-∞< x <∞
Se Z ~ N(0,1) è indipendente da Y ~ χ 2(n), allora
Z
Y
n
E(X)=0,
var(X)=n/(n-2)
~ t(n) .
Le istruzioni per determinare la densità, la funzione di ripartizione e i quantili della v.c. t di Student
sono:
> dt(x, n)
> pt(x, n)
> qt(α, n)
La distribuzione t è simmetrica e platicurtica rispetto alla gaussiana; per n→ ∞, t(n)→ N:
> curve(dnorm(x),-5,5,ylab="")
76
0.3
0.4
> curve(dt(x,1),lty=3,ylab="",add=TRUE)
> legend(2,0.3,c("Z","t"),lty=c(1,3))
0.0
0.1
0.2
Z
t
-4
-2
0
2
4
x
4.5.5 v.c. F
La variabile casuale F ha funzione di densità di probabilità:
f ( x) =
Γ((n + m ) / 2 ) ⎛ n ⎞
⎜ ⎟
Γ(n / 2)Γ(m / 2 ) ⎝ m ⎠
E(X)=m/(m-2)
n/2
n ⎞
⎛
x n / 2 −1 ⎜1 + x ⎟
m ⎠
⎝
se m>2,
var(X)=
Se Y ~ χ 2(n) e W ~ χ 2(m), allora
− (n + m ) / 2
x≥0
2m 2 (n + m − 2)
n(m − 2) (m − 4)
2
se m>4
Y /n
~ F(n,m) .
W /m
Le istruzioni per determinare la densità, la funzione di ripartizione e i quantili della v.c. F sono:
> df(x, n, m)
> pf(x, n, m)
> qf(α, n, m)
Rappresentiamo graficamente una v.c. X~ F(3,2):
0.0 0.1 0.2 0.3 0.4 0.5 0.6
df(x, 3, 2)
> curve(df(x,3,2),0,2)
0.0
0.5
1.0
1.5
2.0
x
77
4.5.6 v.c. esponenziale
La variabile casuale esponenziale ha funzione di densità di probabilità:
f ( x ) = λ e − λx
E(X)=1/λ
x>0
var(X)=1/λ2
Le istruzioni per determinare la densità, la funzione di ripartizione e i quantili della v.c.
esponenziale sono:
> dexp(x, λ)
> pexp(x, λ)
> qexp(α,λ)
Poichè:
- Y ~ Poi(µ) conta il n. di realizzazioni di un evento aleatorio in un intervallo di tempo;
- X ~ Exp(λ) misura il tempo che intercorre tra due di tali eventi successivi (X v.c. tempo d'attesa
continua per la realizzazione successiva dell’evento),
allora
P(Y=0)=P(X>1):
> dpois(0,5)
[1] 0.006737947
> pexp(1,5,lower.tail=FALSE)
[1] 0.006737947
in poche parole, dire che nell’intervallo di tempo unitario non si verificano eventi, vuol dire che il
primo evento si verifica dopo un’unità di tempo
4.5.7 v.c. gamma
La variabile casuale gamma10 ha funzione di densità di probabilità:
f ( x) =
1 a a −1 −λx
λ x e
Γ(a )
x≥0,
a >0, λ>0
E(X)= a /λ
var(X)= a /λ2
Le istruzioni per determinare la densità, la funzione di ripartizione e i quantili della v.c. gamma
sono:
> dgamma(x, a, λ)
> pgamma(x, a, λ)
> qgamma(α, a, λ)
E’ noto che :
X ~ G(1, λ) ~ Exp(λ)
10
v.c. tempo di attesa continua per la realizzazione n-ma di un evento aleatorio
78
3.0
1.5
0.0
dgamma(x, 1, 3)
> par(mfrow=c(2,1))
> curve(dgamma(x,1,3),0,3)
> curve(dexp(x,3),0,3)
> dgamma(1,1,3)
[1] 0.1493612
> dexp(1,3)
[1] 0.1493612
0.0
0.5
1.0
1.5
2.0
2.5
3.0
2.0
2.5
3.0
3.0
1.5
0.0
dexp(x, 3)
x
0.0
0.5
1.0
1.5
x
X ~ G(n/2, 1/2) ~ χ 2(n)
0.00 0.10
dgamma(x, 2, 1/2)
> curve(dgamma(x,2,1/2),0,10)
> curve(dchisq(x,4),0,10)
> dgamma(2,2,1/2)
[1] 0.1839397
> dchisq(2,4)
[1] 0.1839397
0
2
4
6
8
10
6
8
10
0.00 0.10
dchisq(x, 4)
x
0
2
4
x
Se a→ ∞, G(a, λ)→ N(a /λ, a /λ2)
> par(mfrow=c(1,1))
> curve(dgamma(x,1,1),0,10,ylab="",main="densità gamma")
> curve(dgamma(x,2,1),lty=2,add=TRUE)
> curve(dgamma(x,3,1),lty=3,add=TRUE)
> legend(7,0.8,c("a=1","a=2","a=3"),lty=c(1,2,3))
79
0.8
1.0
densità gamma
0.0
0.2
0.4
0.6
a=1
a=2
a=3
0
2
4
6
8
10
x
4.5.8 v.c. beta
La variabile casuale beta ha funzione di densità di probabilità:
f ( x) =
1
b −1
x a −1 (1 − x )
Beta(a, b )
0≤ x ≤1
a >0, b >0
La funzione beta può essere definita in termini della funzione gamma:
Beta(a,b)=
Γ(a )Γ(b ) 1 a −1
b −1
= ∫ x (1 − x ) dx
0
Γ(a + b )
dunque è:
> beta(1,1)
[1] 1
> gamma(1)*gamma(1)/gamma(2)
[1] 1
Le istruzioni per determinare la densità, la funzione di ripartizione e i quantili della v.c. beta sono:
> dbeta(x, a,b)
> pbeta(x, a,b)
> qbeta(α, a,b)
Rappresentiamo graficamente la distribuzione beta al variare di a e b:
> par(mfrow=c(3,2))
> curve(dbeta(x,1,1),0,1,ylim=c(0,3),ylab="",main= "a=b=1")
> curve(dbeta(x,.1,.1),0,1,ylim=c(0,3),ylab="",main= "a<1,b<1")
> curve(dbeta(x,.1,1),0,1,ylim=c(0,3),ylab="",main= "a<1")
> curve(dbeta(x,1,.1),0,1,ylim=c(0,3),ylab="",main= "b<1")
> curve(dbeta(x,2,2),0,1,ylim=c(0,3),ylab="",main="a=b=2" )
> curve(dbeta(x,4,4),0,1,ylim=c(0,3),ylab="",main="a=b=4")
80
0.0 2.5
a<1,b<1
0.0 2.5
a=b=1
x
x
a<1
b<1
0.0
0.0
2.5
0.0 0.2 0.4 0.6 0.8 1.0
2.5
0.0 0.2 0.4 0.6 0.8 1.0
x
x
a=b=2
a=b=4
0.0 2.5
0.0 0.2 0.4 0.6 0.8 1.0
0.0 2.5
0.0 0.2 0.4 0.6 0.8 1.0
0.0 0.2 0.4 0.6 0.8 1.0
0.0 0.2 0.4 0.6 0.8 1.0
x
x
Nei casi in cui a è diverso da b, i parametri determinano l'asimmetria della densità:
> par(mfrow=c(2,1))
> curve(dbeta(x,2,4),0,1,ylim=c(0,3),ylab="",main="a=2,b=4")
> curve(dbeta(x,4,2),0,1,ylim=c(0,3),ylab="",main="a=4,b=2")
0.0 2.5
a=2,b=4
0.0
0.2
0.4
0.6
0.8
1.0
0.8
1.0
x
0.0 2.5
a=4,b=2
0.0
0.2
0.4
0.6
x
4.6 Simulazione di variabili casuali
R, oltre a disporre di funzioni per il calcolo di densità, funzioni di ripartizione e quantili, dispone
anche di una serie di funzioni che consentono di generare realizzazioni di variabili casuali. A tal
fine, il prefisso da premettere al nome della variabile casuale è “r”:
rbinom(r,n,p)
rgeom(r,p)
rnbinom(r,n,p)
rhyper(r,K,N-K,n)
81
rpois(r,µ)
rnorm(r,µ,σ)
runif(r,a,b)
rchisq(r,n)
rt(r,n)
rf(r,n,m)
rexp(r,λ)
rgamma(r,a,λ)
rbeta(r,a,b)
dove l’argomento “r” è il numero di replicazioni.
Proviamo a generare r=1000 replicazioni da una v.c. Z ∼ N(0,1) e ad osservarne il comportamento;
costruiamo l’istogramma, quindi sovrapponiamo ad esso i grafici della densità stimata e della
densità vera:
> x<-rnorm(1000)
> hist(x,freq=FALSE)
> lines(density(x),lty=2)
> curve(dnorm(x),add=TRUE)
0.2
0.0
0.1
Density
0.3
0.4
Histogram of x
-3
-2
-1
0
1
2
3
x
Il comando in R per stimare una densità è “density”. Non soffermandoci sull’argomento, molto
banalmente diciamo che la stima della densità è una sorta di lisciamento del poligono di frequenza,
quindi dell’istogramma.
Al comando “density” premettiamo il comando “lines”, se vogliamo sovrapporre la densità stimata
a un grafico preesistente, viceversa premettiamo il comando “plot”:
> plot(density(x),lty=2)
> curve(dnorm(x),add=TRUE)
> curve(dnorm(x),-3,3)
> lines(density(x),lty=2)
82
5 Campionamento e inferenza
E’ noto che ogni indagine statistica prende in considerazione insiemi di unità (individui, oggetti,
altro), che costituiscono la “popolazione” o il “collettivo statistico”. Spesso condurre un’indagine
sull’intera popolazione risulta oneroso in termini di costo e/o di tempo o addirittura impossibile; la
conoscenza delle caratteristiche di una popolazione può allora essere effettuata sulla base di un
campione, il più possibile rappresentativo di essa. Supponiamo che la caratteristica della
popolazione cui siamo interessati possa essere rappresentata da una v.c. X∼ (µ, σ2).
Sia (X1,X2,…,Xn) un campione casuale estratto da X: Xi i.i.d. (µ, σ2); la v.c. “media campionaria”
1 n
X n = ∑ X i ∼ (µ, σ2/n). Poiché E( X n ) = µ, X n è uno stimatore “corretto” di µ.
n i =1
X −µ
∼ N(0,1).
Se X ∼ N(µ, σ2), X n ∼ N(µ, σ2/n), quindi n
σ2 /n
Uno stimatore corretto di σ2 , quando questa non è nota, è dato dalla “varianza campionaria”
∑ (X
n
S n2 =
i =1
− Xn)
2
i
n −1
. Se Xi i.i.d. N(µ, σ2), (n-1)
S n2
σ
2
~χ 2n-1 e
Xn − µ
S n2 / n
∼ tn-1.
5.1 Legge dei grandi numeri
Se Xi i.i.d. (µ, σ2), con σ2<∞, ∀ε>0, al crescere dell’ampiezza campionaria, la probabilità che la
media campionaria sia esterna all’intervallo µ ±ε tende a zero:
(
)
P Xn − µ >ε → 0,
n→∞.
Quest’espressione afferma che la media calcolata sul campione, all’aumentare di n, si avvicina a µ
con una probabilità molto alta.
Servendoci di un ciclo for, proviamo a generare 20 campioni, di ampiezza n crescente, da una
N(10,22). Calcoliamo la media aritmetica (mn) su ciascun campione quindi, tramite il comando
“plot”, rappresentiamo graficamente le 20 medie rispetto ad n. Il comando “abline” consente di
rappresentare la vera media µ:
> n<-seq(10,1000,50)
>n
[1] 10 60 110 160 210 260 310 360 410 460 510 560 610 660 710 760 810 860 910
[20] 960
> mn<-numeric(20)
> mn
[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> for(i in 1:20){
+ x<-rnorm(n[i],10,2)
+ mn[i]<-mean(x)
+}
> mn
[1] 9.799474 10.387550 10.105870 10.111204 9.915069 9.903249 10.097539
[8] 10.003708 10.103273 9.950783 9.911585 9.960072 9.942577 10.046567
[15] 9.991333 9.984288 10.103710 10.030403 9.975925 9.953915
83
10
8
9
mn
11
12
> plot(n,mn,type="l",ylim=c(8,12))
> abline(h=10,lty=2)
0
200
400
600
800
n
Il comando ‘’numeric‘’ è servito per inizializzare con degli zeri un vettore, in questo caso, di
dimensione 20.
Riutilizziamo adesso la stessa sequenza di comandi k=4 volte, servendoci di un altro ciclo for;
ovviamente i vettori generati, anche se della stessa ampiezza, sono diversi, perché costituiti da
sequenze di numeri pseudo-casuali:
10 11 12
8
9
mn
10 11 12
8
9
mn
> op<-par(mfrow=c(2,2))
> for(k in 1:4){
+ n<-seq(10,1000,50)
+ mn<-numeric(20)
+ for(i in 1:20){
+ x<-rnorm(n[i],10,2)
+ mn[i]<-mean(x)
+}
+ plot(n,mn,type="l",ylim=c(8,12))
+ abline(h=10,lty=2)
+}
> par(op)
0
200
400
600
800
0
200
400
600
800
600
800
10 11 12
8
8
9
mn
10 11 12
n
9
mn
n
0
200
400
n
600
800
0
200
400
n
I grafici generati mostrano che la media campionaria oscilla intorno a µ e si avvicina ad essa con
probabilità molto alta al crescere di n.
84
5.2 Teorema centrale del limite
Asintoticamente, la somma standardizzata di n v.c. Xi i.i.d. (µ, σ2), con σ2 finita, tende a distribuirsi
come una normale standard:
n
∑X
i =1
i
− nµ
∼ N(0,1), quindi
nσ 2
Xn − µ
σ2 /n
∼ N(0,1), se n→∞.
La velocità di convergenza dipende da n e dalla distribuzione di X.
Ad esempio, se X ∼ ber(p), allora pˆ n = X n ∼ bin con E( X n ) = p e var( X n ) = p(1-p)/n. Se però
n→∞, allora bin→N (Teorema di De Moivre-Laplace). La velocità di convergenza dipende da p.
Proviamo a generare, servendoci di un ciclo for, 500 campioni di grandezza n=50 da una v.c. X ∼
ber(0.5). Calcoliamo la media su ciascun campione e costruiamo la distribuzione empirica della
media campionaria standardizzata, quindi adattiamo una N(0,1):
> p<-.5
> n<-50
> mn<-numeric(500)
> for(i in 1:500){
+ x<-rbinom(n,1,p)
+ mn[i]<-mean(x)
+}
> z<-(mn-p)/sqrt(p*(1-p)/n)
> hist(z,freq=FALSE,ylim=c(0,.5),xlim=c(-4,4),col=2,main=paste("n=",n,"\n","p=",p))
> curve(dnorm(x),add=TRUE)
L’istruzione “paste” serve a concatenare due o più stringhe in una sola; tutto ciò che non ha valore
numerico va espresso fra apici, mentre "\n" serve a creare uno spazio.
0.3
0.2
0.0
0.1
Density
0.4
0.5
n= 50
p= 0.5
-4
-2
0
2
4
z
Proviamo adesso a generare campioni di ampiezza crescente, utilizzando un doppio ciclo for:
85
> n<-c(10,50,100,1000)
> p<-.5
> op<-par(mfrow=c(2,2))
> for(k in n){
+ mn<-numeric(500)
+ for(i in 1:500){
+ x<-rbinom(k,1,p)
+ mn[i]<-mean(x)
+}
+ z<-(mn-p)/sqrt(p*(1-p)/k)
+ hist(z,freq=FALSE,ylim=c(0,.6),
+ xlim=c(-4,4),col="red",main=paste("n=",k))
+ curve(dnorm(x),add=TRUE)
+}
0.4
Density
0.0
0
2
4
-4
-2
0
z
z
n= 100
n= 1000
2
4
2
4
0.4
Density
0.0
0.2
0.0
0.2
0.4
0.6
-2
0.6
-4
Density
0.2
0.4
0.2
0.0
Density
0.6
n= 50
0.6
n= 10
-4
-2
0
z
2
4
-4
-2
0
z
Come si può notare, per p=0.5 la convergenza verso la N è evidente anche per n piccolo. Se
proviamo a sostituire, invece, p=0.1, ci accorgiamo che la convergenza verso la N è lenta.
Verifichiamo adesso che se X ∼ N(µ, σ2),
Xn − µ
σ2 /n
∼ N(0,1), a prescindere dal valore di n:
> n<-c(10,50,100,1000)
> for(k in n){
+ mn<-numeric(500)
+ for(i in 1:500){
+ x<-rnorm(k,5,2)
+ mn[i]<-mean(x)
+}
+ z<-(mn-5)/sqrt(4/k)
+ hist(z,freq=FALSE,ylim=c(0,.6),
+ xlim=c(-4,4),col="red",main=paste("n=",k))
+ curve(dnorm(x),-4,4,add=TRUE)
+}
> par(op)
86
0.4
0.0
0
2
4
-4
-2
0
z
z
n= 100
n= 1000
2
4
2
4
0.4
0.2
0.0
0.0
0.2
Density
0.4
0.6
-2
0.6
-4
Density
0.2
Density
0.4
0.2
0.0
Density
0.6
n= 50
0.6
n= 10
-4
-2
0
2
4
-4
-2
z
0
z
5.3 Funzione di (log)verosimiglianza
Siano (X1,X2,…,Xn) n v.c. la cui densità (probabilità) congiunta è f(x1,x2,…,xn;θ). Se (X1,X2,…,Xn) è
un campione casuale estratto da X∼ f(x;θ), per cui le Xi sono i.i.d., allora è
n
f(x1,x2,…,xn;θ)= ∏ f (xi;θ).
i =1
Tale densità (probabilità) congiunta, osservato il campione (x1,x2,…,xn), diventa funzione solo di θ e
prende il nome di “funzione di verosimiglianza”, che indichiamo con L(θ, x1,x2,…,xn), o più
semplicemente con L(θ).
Con il metodo della massima verosimiglianza si assume come stima di θ il valore θˆ che rende
massima la funzione di verosimiglianza, ossia la probabilità del campione osservato. La
determinazione della stima di massima verosimiglianza si concretizza dunque nella ricerca del
massimo della funzione L(θ) o, equivalentemente, della funzione log L(θ)11.
Supponiamo di estrarre un campione di grandezza n=3 da X ~ ber(p). I possibili campioni sono:
(0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (0, 1, 1), (1, 0, 1), (1, 1, 1).
La funzione di verosimiglianza è: L(p)=pΣx(1-p)n-Σx, dunque può essere rappresentata dalle seguenti
4 curve (Σx=0, 1, 2, 3), in cui l‘ascissa del punto di massimo è la stima di massima verosimiglianza
n
pˆ =
∑x
i =1
n
i
di p:
> L0<-function(p) (1-p)^3
> curve(L0,0,1, xlab="p",ylab="L(p)")
> L1<-function(p) p*(1-p)^2
> curve(L1,0,1,add=TRUE,col=2)
> L2<-function(p) (p^2)*(1-p)
11
Ricercare il massimo di L(θ), o di log L(θ), equivale a ricercare il minimo di -L(θ), o di -log L(θ)
87
0.6
0.4
0.0
0.2
L(p)
0.8
1.0
> curve(L2,0,1,add=TRUE,col=3)
> L3<-function(p) p^3
> curve(L3,0,1,add=TRUE,col=4)
0.0
0.2
0.4
0.6
0.8
1.0
p
Generiamo, adesso, un campione di grandezza n=50 da una v.c. X ∼ ber(0.2) e rappresentiamo la
funzione logL(p). Calcoliamo, inoltre, la stima di massima verosimiglianza di p e tracciamo due
rette parallele agli assi, passanti per il punto di massimo, in modo da individuare tale stima anche
graficamente:
-100
-150
logL(p)
-50
> n<-50
> x<-rbinom(n,1,.2)
> y<-sum(x)
> lnL<-function(p)
+{
+ y*log(p)+(n-y)*log(1-p)
+}
> curve(lnL,0,1,xlab="p",ylab="logL(p)")
> xmax<-mean(x)
> xmax
[1] 0.18
> ymax<-lnL(xmax)
> abline(v=xmax,lty=3)
> abline(h=ymax,lty=3)
0.0
0.2
0.4
0.6
0.8
1.0
p
88
Generiamo, infine, un campione di grandezza n=50 da una v.c. X ∼ N(5,4) e rappresentiamo le
∑ ( xi − µ )2
( x i − µ )2
n
∑
i
⎛ 1 ⎞ −
n
⎟⎟ e 2σ 2
e
-logL(µ,σ)= n log(σ ) + log(2π ) + i
,
funzioni
L(µ,σ)= ⎜⎜
2
2σ 2
⎝ σ 2π ⎠
n
considerando noto σ. Calcoliamo, quindi, la stima di massima verosimiglianza µ̂ =
6.0 e-48
0.0 e+00
L(µ)
1.2 e-47
> n<-50
> s2<-4
> x<-rnorm(n,5,sqrt(s2))
> sx<-sum(x)
> sx2<-sum(x^2)
> L<-function(m)
+{
+ k<-1/(sqrt(2*pi*s2))^n
+ k*exp((-1/(2*s2))*(sx2-2*m*sx+n*m^2))
+}
> curve(L,4,7,xlab=expression(mu),ylab=expression(L(mu)))
> xmax<-mean(x)
> xmax
[1] 5.041527
> ymax<-L(xmax)
> ymax
[1] 1.397241e-47
> abline(v=xmax,lty=3)
> abline(h=ymax,lty=3)
4.0
4.5
5.0
5.5
6.0
6.5
7.0
µ
> n<-50
> s<-2
> x<-rnorm(n,5,s)
> sx<-sum(x)
> sx2<-sum(x^2)
> lnL<-function(m)
+{
+ k<-(n/2)*log(2*pi)+n*log(s)
+ k+(sx2-2*m*sx+n*m^2)/(2*(s^2))
+}
89
∑x
i =1
n
i
di µ:
200
100
150
logL(µ)
250
> curve(lnL,0,10,,xlab=expression(mu),ylab=expression(logL(mu)))
> xmin<-mean(x)
> ymin<-lnL(xmin)
> ymin
[1] 106.7508
> abline(v=xmin,lty=3)
> abline(h=ymin,lty=3)
0
2
4
6
8
10
µ
5.4 Intervalli di confidenza
5.4.1 IC per la media
E’ noto che con i metodi di stima puntuale si giunge alla determinazione di un solo valore dello
stimatore del parametro; con la stima per intervallo, invece, si giunge alla determinazione di un
intervallo che, con una data probabilità, dovrebbe comprendere il vero valore del parametro θ. Se si
conosce la distribuzione campionaria di uno stimatore θˆ , è possibile ricavare la probabilità (1-α)
che θˆ cada in un intervallo prefissato. Ad esempio, se (X1,X2,…,Xn) è un campione casuale estratto
X −µ
∼ N(0,1), quindi è
da X ∼ N(µ, σ2), la v.c. “media campionaria” X n ∼ N(µ, σ2/n), ovvero n
σ2 /n
lecito scrivere:
X −µ
≤ z1-α/2) = 1-α
P(zα/2 ≤ n
σ2 /n
Per α =0.05, è zα/2 = -1.96 e z1-α/2 =1.96, infatti:
> qnorm(.025)
[1] -1.959964
> # oppure
> -qnorm(.975)
[1] -1.959964
> qnorm(.975)
[1] 1.959964
Ovviamente è zα/2 = - z1-α/2 , perché la v.c. N è simmetrica.
90
Rappresentiamo graficamente la suddetta probabilità, utilizzando comandi già noti:
> curve(dnorm(x),-3,3,axes=FALSE,ylab="",xlab="",ylim=c(0,.5))
> axis(1,c(-3,-1.96,0,1.96,3),c("","-1.96",0,"1.96",""))
> cods<-seq(-3,-1.96,length=100)
> x<-c(-3,cods,-1.96,-3)
> y<-c(0,dnorm(cods),0,0)
> polygon(x,y,col=2)
> codd<-seq(1.96,3,length=100)
> x<-c(1.96,codd,3,1.96)
> y<-c(0,dnorm(codd),0,0)
> polygon(x,y, col=2)
> abline(h=0)
> text(0,.1,expression(1-alpha==0.95))
> text(-2.5,.1,expression(alpha/2==0.025))
> text(2.5,.1,expression(alpha/2==0.025))
> text(0,.5,expression(P(-1.96<Z<1.96)==1-alpha))
P ( − 1.96 < Z < 1.96) = 1 − α
α 2 = 0.025
-1.96
1 − α = 0.95
0
α 2 = 0.025
1.96
L’espressione
P(-1.96 ≤
Xn − µ
σ2 /n
≤ 1.96) = 0.95
può anche scriversi nel seguente modo:
P( X n -1.96 σ 2 / n ≤ µ ≤ X n +1.96 σ 2 / n ) = 0.95
L’ntervallo X n ± 1.96 σ 2 / n è un “intervallo di confidenza” per µ, perché nel 95% dei casi,
ovvero per 95 campioni su 100, contiene µ.
Facciamo un esempio, supponendo σ2 nota.
Un urbanista è interessato alla superficie media µ delle abitazioni della propria città. Uno studio
precedente indica che σ2=8 m2. In un campione di 50 appartamenti si osserva una media pari a 120
m2. Sulla base di questi dati si vuole determinare l'IC per µ al 95%. In R possiamo utilizzare i
seguenti comandi:
91
> n<-50
> mx<-120
> var<-8^2
> #lc<-0.95
> #a<-0.05
> li<-mx-qnorm(.975)*sqrt(var/n)
> ls<-mx+qnorm(.975)*sqrt(var/n)
> cat("(",li,":",ls,")\n")
( 117.7826 : 122.2174 )
L’istruzione “cat” serve a concatenare elementi e a visualizzarli; l’espressione "\n", già vista
all’interno dell’istruzione “paste” (cfr.par.5.2), consente di creare uno spazio.
Supponiamo adesso σ2 non nota.
Su una piastrina di silicio è stato rilevato il peso X in g di alcuni granelli di polvere. Si ipotizzi che
X ~ N. Costruiamo un IC per µ:
> x<-c(.39,.68,.82,1.35,1.38,1.62,1.70,1.71,1.85,2.14,2.89,3.69)
> n<-length(x)
> mx<-mean(x)
> s2<-var(x)
> #lc<-0.95
> #a<-0.05
> li<-mx-qt(.975,n-1)*sqrt(s2/n)
> ls<-mx+qt(.975,n-1)*sqrt(s2/n)
> cat("(",li,":",ls,")\n")
( 1.099159 : 2.270841 )
Si noti come, essendo σ2 non nota, per costruire l’IC ci siamo serviti dei quantili della t di Student;
X −µ
infatti, in questo caso è n
∼ tn-1.
S n2 / n
Lo stesso IC può essere costruito con R tramite il comando “t.test”, che vuole in input il campione e
l’opzione “conf.lev”, se il livello di confidenza (1-α) è diverso da 0.95:
> t.test(x)
One Sample t-test
data: x
t = 6.3305, df = 11, p-value = 5.595e-05
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
1.099159 2.270841
sample estimates:
mean of x
1.685
> t.test(x,conf.lev=0.99)
92
One Sample t-test
data: x
t = 6.3305, df = 11, p-value = 5.595e-05
alternative hypothesis: true mean is not equal to 0
99 percent confidence interval:
0.8583201 2.5116799
sample estimates:
mean of x
1.685
Ricordiamo che minore è l’ampiezza L dell’IC, maggiore è la precisione della stima, dunque per
una scelta ottimale dell’ampiezza campionaria n, fissati α e K, è necessario che sia:
L(n,α)=2 z1-a/2 σ 2 / n < K
da cui
n>(2 z1-a/2 σ / K)2.
5.4.2 IC per una proporzione
Supponiamo che gli elettori siano stati chiamati alle urne per un referendum e che lo spoglio
parziale di n=2000 schede abbia registrato una percentuale favorevole pari al 60%. Si vuole
costruire l’IC al 95% della percentuale favorevole.
Poiché (X1,X2,…,Xn) è un campione casuale estratto da X ∼ ber(p), e poiché n→∞, pˆ n = X n ∼ N(
p,p(1-p)/n).
Dunque:
> p<-0.60
> n<-2000
> li<-p-qnorm(.975)*sqrt(p*(1-p)/n)
> ls<-p+qnorm(.975)*sqrt(p*(1-p)/n)
> cat("(",li,":",ls,")\n")
( 0.5785297 : 0.6214703 )
Con R è possibile costruire un IC molto vicino a quello trovato con il comando “prop.test”, che ha
come argomenti il numero di casi favorevoli, la dimensione del campione e, se non si desidera la
correzione per la continuità di Yates, l’opzione “ corr=FALSE ”:
> x<-n*p
> prop.test(x, n, corr=FALSE)
1-sample proportions test without continuity correction
data: x out of n, null probability 0.5
X-squared = 80, df = 1, p-value = < 2.2e-16
alternative hypothesis: true p is not equal to 0.5
95 percent confidence interval:
0.5783577 0.6212589
93
sample estimates:
p
0.6
> prop.test(x, n)
1-sample proportions test with continuity correction
data: x out of n, null probability 0.5
X-squared = 79.6005, df = 1, p-value = < 2.2e-16
alternative hypothesis: true p is not equal to 0.5
95 percent confidence interval:
0.5781060 0.6215062
sample estimates:
p
0.6
Per n piccolo, pˆ n = X n ∼ bin. In questo caso per costruire un IC per p, si può utilizzare il comando
“binom.test”:
> binom.test(x,n)
Exact binomial test
data: x and n
number of successes = 1200, number of trials = 2000, p-value = <
2.2e-16
alternative hypothesis: true probability of success is not equal to 0.5
95 percent confidence interval:
0.5781459 0.6215604
sample estimates:
probability of success
0.6
5.4.3 IC per la varianza
Riprendendo l’esempio della piastrina di silicio, su cui era stato rilevato il peso X in g di alcuni
granelli di polvere, proviamo a costruire una funzione, che chiamiamo “icvar”, che determini un IC
per σ2.
S2
Se (X1,X2,…,Xn) è un campione casuale estratto da X ~ N(µ, σ2), allora (n-1) n2 ~χ 2n-1, quindi è
σ
lecito scrivere:
P(χ 2α/2 < (n-1)
S n2
σ
2
< χ 21-α/2 )=1-α
ovvero:
P(
(n − 1) S n2
χ 12−α / 2
<σ2 <
94
(n − 1) S n2
χ α2 / 2
)=1-α
Un IC per σ2 è allora:
> icvar<-function(x,lc=0.95)
+{
+ a<-1-lc
+ n<-length(x)
+ li<-(n-1)*var(x)/qchisq(1-a/2, n-1)
+ ls<-(n-1)*var(x)/qchisq(a/2, n-1)
+ c(li,ls)
+}
> x<-c(.39,.68,.82,1.35,1.38,1.62,1.70,1.71,1.85,2.14,2.89,3.69)
> var(x)
[1] 0.8501727
> icvar(x)
[1] 0.4266368 2.4508692
Ovviamente, in questo caso, è χ 2α/2 ≠ -χ 21-α/2 , poiché la v.c. χ 2 non è simmetrica; fra l’altro, la v.c.
χ 2 non assume valori negativi:
0.06
0.04
0.00
0.02
dchisq(x, n - 1)
0.08
> n<-length(x)
> curve(dchisq(x,n-1),-1,30)
> qchisq(.025,n-1)
[1] 3.815748
> -qchisq(.975,n-1)
[1] -21.92005
> qchisq(.975,n-1)
[1] 21.92005
0
5
10
15
20
25
30
x
5.5 Verifica di ipotesi
Supponiamo di avere un'idea di quale possa essere il valore incognito di un parametro θ; studiamo
una strategia che, sulla base dei dati osservati, consenta di confermare o smentire la nostra ipotesi
iniziale H0.
Per sottoporre a verifica un’ipotesi ci serviamo di una statistica test.
Il test ci dirà se rifiutare o accettare l' ipotesi nulla H0 ma, nel far questo, possiamo incorrere:
- in un errore di I tipo (α), se rifiutiamo H0 ed H0 è vera;
95
- in un errore di II tipo (β), se accettiamo H0 ed H0 è falsa.
5.5.1 Verifica di ipotesi per la media
Fissato α, supponiamo di voler verificare l’ipotesi H0: µ =µ0, contro l’ipotesi alternativa H1: µ <µ0.
Se (X1,X2,…,Xn) è un campione casuale estratto da X ∼ N, la “statistica test” Z =
X n − µ0
σ 2 /n
∼ N(0,1).
Trattandosi di un test a una coda, rifiuteremo H0 se z<zα, dove z = ( x n -µ0)/ σ 2 / n è il valore di Z
calcolato sul campione.
Volendo verificare, invece, l’ipotesi H0: µ =µ0, contro l’alternativa H1: µ >µ0, rifiuteremo H0 se
z>z1-α. Se σ2 non è nota, e viene stimata con la varianza campionaria, bisogna ricordarsi che
X n − µ0
∼ tn-1.
S n2 / n
Facciamo un esempio. In un campione di pazienti trattati con una terapia per l’abbassamento del
colesterolo si sono osservati i seguenti valori di colesterolo in milligrammi per 100 millilitri di
sangue:
130, 145, 128, 169, 132, 138, 141, 153, 129, 135, 140.
Sapendo che in una popolazione di persone sane la quantità di colesterolo, che si suppone essere
distribuita normalmente, in media è pari a 130, cosa fare per stabilire se la terapia adottata ha avuto
effetto?
Si tratta di verificare l’ipotesi H0: µ =130, contro l’alternativa H1: µ >130. Inoltre, σ2 non è nota,
dunque, possiamo procedere nel seguente modo:
> x<-c(130, 145, 128, 169, 132, 138, 141, 153, 129, 135, 140)
>x
[1] 130 145 128 169 132 138 141 153 129 135 140
> mean(x)
[1] 140
> m0<-130
> var(x)
[1] 149.4
> m<-mean(x)
> v<-var(x)
> n<-length(x)
> t<-(m-m0)/sqrt(v/n)
>t
[1] 2.713445
>a<-0.01
> qt(1-a, n-1)
[1] 2.763769
Fissato α=0.01, poiché t<t1-0.01, non rifiutiamo H0. Lo scarto (140-130) non è statisticamente
significativo. Ciò vuol dire che la terapia adottata non ha avuto effetto.
96
Agli stessi risultati si perviene utilizzando la funzione “t.test”, già vista per la costruzione di un IC
per µ; in questo caso, però, bisogna specificare µ0 e se l’ipotesi alternativa è “g” (greater), come
nell’esempio, o “l” (less):
> t.test(x,mu=m0,alternative="greater")
One Sample t-test
data: x
t = 2.7134, df = 10, p-value = 0.01090
alternative hypothesis: true mean is greater than 130
95 percent confidence interval:
133.3204 Inf
sample estimates:
mean of x
140
Ricordiamo che il p-value è qui così definito: p-value = P(X>t), dove X∼ tn-1 In questo caso pvalue>α, quindi t non si trova nella zona di rifiuto.
5.5.2 Verifica di ipotesi per una proporzione
Facciamo un esempio. Il direttore del personale di una compagnia di assicurazioni intende ridurre il
turn-over, nel primo anno di assunzione, degli impiegati addetti all’analisi dei dati. Analisi
precedenti mostrano che il 25% di coloro che vengono assunti in quest’area lascia la compagnia
entro l’anno successivo all’assunzione. 150 neo assunti sono sottoposti ad un nuovo programma di
training. Di questi, alla fine del primo anno, 29 non lavorano più per la compagnia.
Fissato un livello di significatività pari a 0.05, si può ritenere che la proporzione di impiegati addetti
all’analisi dei dati, che hanno partecipato al nuovo programma di training e poi lasciato la
compagnia, sia inferiore al 25%?
Si tratta di verificare l’ipotesi H0: p=p0 contro l’ipotesi alternativa H1: p<p0.
Se (X1,X2,…,Xn) è un campione casuale estratto da X ∼ ber(p), per n→∞, la “statistica test”
pˆ n − p 0
∼ N(0,1). Quindi:
( p 0 (1 − p 0 ) / n
> p<-29/150
>p
[1] 0.1933333
> p0<-25/100
> n<-150
> z<-(p-p0)/sqrt(p0*(1-p0)/n)
>z
[1] -1.602775
> qnorm(0.05) # quantile
[1] -1.644854
97
> pnorm(z) # p-value
[1] 0.05449213
Poichè z>z0.05 e p-value>α, z non si trova nella zona di rifiuto, per cui la differenza ( pˆ n − p 0 ) non si
può ritenere statisticamente significativa. Possiamo concludere, dunque, che la proporzione di
impiegati addetti all’analisi dei dati, che hanno partecipato al nuovo programma di training e poi
lasciato la compagnia, non è inferiore al 25%.
Per la verifica di ipotesi su p si possono anche utilizzare le funzioni “prop.test”, o “binom.test” se n
è piccolo, già analizzate per la costruzione di IC , specificando se l’ipotesi alternativa è “less” o
“greater”. Tali funzioni però seguono una procedura diversa da quella classica, per cui non sempre
si perviene agli stessi risultati:
> prop.test(29,150,alternative="less")
1-sample proportions test with continuity correction
data: 29 out of 150, null probability 0.5
X-squared = 55.2067, df = 1, p-value = 5.425e-14
alternative hypothesis: true p is less than 0.5
95 percent confidence interval:
0.0000000 0.2552202
sample estimates:
p
0.1933333
> binom.test(29,150,alternative="less")
Exact binomial test
data: 29 and 150
number of successes = 29, number of trials = 150, p-value = 7.309e-15
alternative hypothesis: true probability of success is less than 0.5
95 percent confidence interval:
0.0000000 0.2541129
sample estimates:
probability of success
0.1933333
5.5.3 Verifica di ipotesi per la varianza
Supponiamo di voler verificare l’ipotesi H0: σ2 =σ02 contro l’alternativa H1: σ2 >σ02 oppure contro
l’alternativa H1: σ2 <σ02. Costruiamo, a tale proposito, una funzione, che definiamo “testvar”,
tenendo conto che se (X1,X2,…,Xn) è un campione casuale estratto da X ~ N, la “statistica test”
S n2
(n-1) 2 ~χ 2n-1.
σ0
La funzione “testvar” chiede, inizialmente, se (if) σ02 e i dati campionari sono “missing”, altrimenti
blocca (stop) la routine e chiede di inserirli. Successivamente, definisce la statistica test “stat” e
tramite istruzioni “if” nidificate chiede:
98
-
se H1: σ2 >σ02, in tal caso il valore “soglia” è χ 21-α; se (n-1)
-
se H1: σ2 <σ02, in tal caso il valore “soglia” è χ 2α; se (n-1)
s n2
σ 02
s n2
σ 02
>χ 21-α, si rifiuta H0;
<χ 2α, si rifiuta H0.
Una serie di istruzioni “cat”, infine, consentono di visualizzare dei messaggi.
La funzione “testvar” vuole in input: i dati campionari, σ02, l’opzione “greater” o “less”, che
specifica l’ipotesi alternativa, il valore di α se è diverso da 0.05:
testvar<-function (x, var0, alternative = c("greater", "less"), alpha = 0.05)
{
if (missing(var0))
stop("specificare l'ipotesi nulla var0")
if (missing(x))
stop("specificare i dati x")
n <- length(x)
stat <- (n - 1) * var(x)/var0
cat("\n Ipotesi nulla => H0 : var =", var0)
cat("\n Varianza campionaria:", var(x), ",")
cat(" statistica test:", stat)
if (alternative == "greater") {
soglia <- qchisq(1 - alpha, df = n - 1)
cat("\n p-value:", 1 - pchisq(stat, df = n - 1), ",")
cat(" livello del test:", alpha)
cat("\n Quantile Chi-quadrato:", soglia, " con ", n 1, "gdl")
cat("\n Ipotesi alternativa => H1 : var > ", var0)
if (stat > soglia)
cat("\n Decisione: si rifuta H0\n")
else cat("\n Decisione: non si rifuta H0\n")
}
else if (alternative == "less") {
soglia <- qchisq(alpha, df = n - 1)
cat("\n p-value:", pchisq(stat, df = n - 1), ",")
cat(" livello del test:", alpha)
cat("\n Quantile Chi-quadrato:", soglia, " con ", n 1, "gdl")
cat("\n Ipotesi alternativa => H1 : var < ", var0)
if (stat < soglia)
cat("\n Decisione: si rifuta H0\n")
else cat("\n Decisione: non si rifuta H0\n")
}
}
Nel costruire la funzione “testvar” abbiamo ipotizzato la media non nota.
Facciamo un esempio. Estraiamo un campione di dimensione n=100 da una N(0,52):
> x<-rnorm(100,sd=5)
> var(x)
[1] 24.26047
99
Fissato α=0.05, vogliamo verificare l’ipotesi H0: σ2 =25 contro l’alternativa H1: σ2 <σ02;
utilizziamo la funzione “testvar”:
> var0<-25
> testvar(x,var0,"less")
Ipotesi nulla => H0 : var = 25
Varianza campionaria: 24.26047 , statistica test: 96.07148
p-value: 0.4353808 , livello del test: 0.05
Quantile Chi-quadrato: 77.04633 con 99 gdl
Ipotesi alternativa => H1 : var < 25
Decisione: non si rifuta H0
100
Appendice
(esercizi svolti)
101
ESERCIZI MODULO 1
1) Considerare il dataframe “chickwts” dell’ambiente R e costruire una tabella a doppia entrata per
le due variabili “weight (Y)” e “feed (X)”, quindi individuare le distribuzioni marginali e la
distribuzione condizionata di Y|X=x4 . Verificare, inoltre, se c’è associazione fra le due variabili.
Calcolare, infine, i quartili per la variabile Y e rappresentare graficamente la variabile X.
2) Il file “azioni.txt” contiene i prezzi (in dollari) di chiusura di 75 azioni, scambiate su due diversi
mercati americani. Per ciascuna delle due serie di dati:
•
Costruire la distribuzione delle frequenze e la distribuzione delle percentuali con
intervalli di ampiezza costante pari a 10 dollari;
•
costruire l’istogramma (rappresentarli entrambi in un unico grafico);
•
calcolare le frequenze cumulate assolute, relative e percentuali;
•
calcolare gli indici di sintesi più informativi;
•
costruire il diagramma scatola e baffi.
Sulla base delle precedenti elaborazioni si possono osservare sostanziali differenze nei
prezzi di chiusura sui due mercati?
3) Il file “funds.txt” contiene informazioni su un campione di 140 fondi di investimento sul quale
sono state osservate le cinque variabili:
A: Tipo di azioni che compongono il fondo;
B: Commissioni di uscita (Y=Si, N=No);
C: Rendimento percentuale ottenuto nel primo semestre del 1999;
D: Rendimento percentuale a dodici mesi;
E: Spese associate al fondo (in percentuale rispetto alle attività).
•
Per la variabile A: costruire la distribuzione delle frequenze assolute, relative e
percentuali; calcolare la moda, calcolare l’indice di eterogeneità di Gini; effettuare una
rappresentazione grafica;
102
•
Per la variabile E: costruire una distribuzione di frequenza per classi di ampiezza
costante, rappresentare l’istogramma, calcolare l’indice di asimmetria più informativo;
•
Calcolare la covarianza tra le variabili C e D;
•
Commentare i risultati ottenuti.
4) I dati (espressi in migliaia di dollari) contenuti nel file “tax.txt” rappresentano dichiarazioni per
l’imposta sulle vendite, sottoposte all’autorità fiscale competente della comunità di Gmoserville, a
fine marzo 1999, dalle 50 aziende ivi operanti.
•
Costruire una distribuzione di frequenza per classi di ampiezza costante e scegliere la
rappresentazione grafica più idonea;
•
calcolare le frequenze relative, le frequenze assolute cumulate, le frequenze relative
cumulate;
•
calcolare gli indici di sintesi più informativi;
•
costruito il diagramma scatola e baffi, come descrivereste la forma della distribuzione?
L’indice di asimmetria, calcolato in precedenza, conferma tale descrizione?
5) Importare il file di dati “aaupdat”, la cui descrizione è contenuta nel file di testo “aauptxt”.
•
Considerare la variabile D, classificarla e scegliere la rappresentazione grafica più
idonea;
•
Considerare le variabili E, F, G, H. Per ciascuna di esse calcolare i quartili e costruire il
boxplot, quindi commentare e confrontare la forma delle 4 distribuzioni;
•
Considerare le variabili E, I. Calcolare la covarianza e il coefficiente di correlazione
lineare di Bravais-Pearson e commentare i risultati.
Costruire la distribuzione di frequenza di una delle due variabili, scegliendo opportune
classi di ampiezza costante e scegliere la rappresentazione grafica più appropriata.
6) Considerare il dataframe “cars” e verificare se sussiste una relazione lineare fra le due variabili
“speed” e “dist”. In tal caso, condurre una completa analisi di regressione.
7) Considerare il dataset contenuto nel file “water”.
•
Stabilire se esiste una relazione fra le due variabili ed individuare la funzione che
rappresenti al meglio tale relazione;
•
Verificare, attraverso l’uso di un indice appropriato, se la suddetta funzione si adatta
bene ai dati osservati.
103
8) Considerare il dataset contenuto nel file “hospital”. Rappresentare graficamente i dati osservati e
verificare, empiricamente ed analiticamente, se esiste una relazione lineare fra le due variabili.
9) Il dataset contenuto nel file “ring.txt” riporta i prezzi, in dollari, di anelli con diamante per
signora e la corrispondente misura del diamante in carati.
•
Individuare la variabile dipendente e rappresentare graficamente le coppie di
osservazioni;
•
stabilire il tipo di relazione che lega le due variabili ed adattare la funzione di
regressione che si ritiene più idonea;
•
determinare un indice che dia indicazioni sulla bontà di adattamento del modello scelto
ai dati osservati.
10) Il dataset contenuto nel file “phone.txt” riporta i valori delle tariffe telefoniche (in dollari, per
minuto di conversazione) e il numero di minuti di conversazione (in miliardi) per le telefonate fatte
dagli Stati Uniti verso 20 paesi, nel corso del 1996.
•
Calcolare il coefficiente di correlazione;
•
Ci si aspetta che quanto maggiore è la tariffa telefonica, tanto minore è la durata delle
telefonate. Il coefficiente di correlazione calcolato conferma tale supposizione?
11) Un agente immobiliare intende prevedere gli affitti mensili degli appartamenti sulla base della
loro dimensione. Nel file “rent.txt” si riportano i valori degli affitti (in dollari) e della dimensione
(in piedi al quadrato) di 25 appartamenti in una zona residenziale.
•
Creare il diagramma di dispersione;
•
Nell’ipotesi che tra le due variabili sussista una relazione lineare, stimare con il metodo
dei minimi quadrati i coefficienti di regressione a e b;
•
fornire un’interpretazione di a e di b con riferimento al problema considerato;
•
prevedere l’ammontare dell’affitto mensile per un appartamento di 1000 piedi al
quadrato;
•
calcolare i residui e i valori predetti;
•
calcolare il coefficiente di determinazione e interpretarne il significato.
104
ESERCIZI MODULO 2
1) L’assistenza ai clienti di una società del gas intende stimare la durata media del tempo X che
intercorre tra la ricezione di una richiesta di allacciamento e l’effettivo allacciamento. Viene estratto
un campione casuale di 15 case, per cui si ottengono i seguenti risultati in numero di giorni di attesa
( i dati si riferiscono all’anno trascorso):
•
114
78
96
137
78
103
117
126
86
99
114
72
104
73
86
Determinare un intervallo di confidenza di livello 95% per stimare la media del
tempo di attesa dello scorso anno;
•
Quale ipotesi si deve fare sulla distribuzione della popolazione?
2) Un imprenditore valuta l’acquisto di una lavanderia a gettoni. L’attuale proprietario sostiene di
aver conseguito, nel corso degli ultimi 5 anni, un guadagno medio giornaliero di $675 con uno
scarto quadratico medio di $75. Per un campione di 30 giorni, si calcola un guadagno medio di
$625.
•
specificare l’ipotesi nulla e quella alternativa;
•
si può ritenere, in base al campione, che l’affermazione dell’attuale proprietario non
sia corretta? (Usare un livello di significatività di 0.01)
3) Supponiamo che in questo momento 10 persone siano collegate ad un sito per l’acquisto di
articoli su Internet. Sapendo che la probabilità che ciascuno dei soggetti acquisti effettivamente un
articolo è pari a 0.2, calcolare:
•
la probabilità che nessun soggetto acquisti un articolo;
•
la probabilità che almeno 2 soggetti acquistino un articolo;
•
la probabilità che al massimo 2 soggetti acquistino un articolo.
105
4) Sono stati rilevati i prezzi al litro di venti acque minerali (lire/10): 31, 35, 36, 34, 40, 38, 68, 46,
28, 33, 21, 34, 30, 42, 20, 34, 63, 22, 38, 28. Supposto che la distribuzione dei prezzi sia N(µ, σ2), si
chiede di verificare l’ipotesi H0: σ2 = σ02 = 200 contro l’alternativa H1: σ2 < 200, al livello di
significatività 0,01.
5) Sia data la seguente variabile casuale bivariata:
X\Y
7
9
11
12
4
0.1
0.1
0.2
0.1
6
0.2
0.1
0.1
0.1
•
verificare se le v.c. X e Y sono stocasticamente indipendenti;
•
determinare E(X) e var(X);
•
determinare E(X+Y) e var(X+Y).
6) Un manager di una società che vende combustibile per riscaldamento domestico intende stimare
il consumo medio annuo (in galloni) nelle case monofamiliari di una certa area geografica. Si estrae
un campione di 35 case: il loro consumo annuo è riportato nella tabella seguente:
1150.25
872.37
1459.56
941.96
1013.27
•
1352.67
1126.57
1252.01
767.37
1402.59
983.45
1184.17
373.91
1598.57
1069.32
1365.11
1046.35
1047.40
1598.66
1108.94
942.71
1110.50
1064.46
1343.29
1326.19
1577.77
1050.86
1018.23
1617.73
1074.86
330.00
851.60
996.92
1300.76
975.86
Calcolare un intervallo di confidenza del 95% per la media della popolazione del
consumo di combustibile per riscaldamento in un anno.
•
E’ necessario fare delle assunzioni sulla distribuzione della popolazione affinché
l’intervallo di confidenza trovato possa ritenersi valido?
7) Il direttore di un grande giornale cittadino intende determinare la proporzione di giornali
stampati, che non sono idonei alla vendita per motivi diversi, come impaginazione sbagliata, pagine
mancanti e così via. Viene allora estratto un campione di 200 giornali e si osserva che 35 di essi non
sono idonei. Calcolare l'intervallo di confidenza del 90% per la proporzione di giornali non idonei
nella popolazione.
8) Il file “tea.txt” riporta i pesi in grammi di 105 bustine di tè.
106
•
In base alle informazioni campionarie, si può ritenere che il peso medio delle bustine
di tè prodotte sia diverso da 5.5 grammi? (Supporre che il livello di significatività α
sia 0.01);
•
Costruire un intervallo di confidenza del 99% per il peso medio dei sacchetti di tè e
spiegarne il significato.
9) Il responsabile del controllo qualità della Malilyn’s cookies sta ispezionando una partita di
biscotti con scaglie di cioccolato di produzione della società. Se il processo produttivo
funziona correttamente il n. medio di scaglie di cioccolato per biscotto è pari a 6.
Qual è la probabilità che in un particolare biscotto ispezionato:
•
si trovino al più 5 scaglie di cioccolato;
•
si trovino esattamente 5 scaglie di cioccolato;
•
si trovino almeno 5 scaglie di cioccolato;
•
si trovino 4 o 5 scaglie di cioccolato.
10) Quando un consumatore fa un ordine attraverso il Rudi’s On-line Office, un sistema
informativo computerizzato controlla automaticamente se il consumatore ha ecceduto i propri limiti
di credito. La probabilità che questa eventualità si verifichi è stata stimata sulla base dell’esperienza
pari a 0.05. Supponendo che in un giorno siano inoltrati 20 ordini da parte di altrettanti consumatori
e che il numero di ordini oltre i limiti di credito sia distribuito secondo una legge binomiale,
calcolare:
•
Il valore atteso e lo scarto quadratico medio del numero di ordini oltre i limiti di
credito;
•
la probabilità che in un giorno nessun consumatore inoltri un ordine che ecceda il
proprio limite di credito;
•
la probabilità che almeno due consumatori eccedano i propri limiti di credito;
•
la probabilità che al più tre consumatori eccedano i propri limiti di credito.
11) Una filiale di una banca, in un quartiere commerciale di una città, ha realizzato un
miglioramento nel servizio alla clientela tra le 12 e le 13, l’ora di punta della pausa pranzo. Per una
settimana viene rilevato il tempo di attesa (in minuti) di ciascun cliente (definito come il tempo che
intercorre tra il momento in cui inizia la fila e quello in cui è servito). Per un campione casuale di
15 clienti si ottengono i risultati riportati nel file “bank.txt”.
107
•
Fissato un livello di significatività pari a 0.05, si può ritenere che il tempo medio di
attesa sia inferiore a 5 minuti?
•
verificare l’ipotesi H0: σ2 = σ02 = 2 contro l’alternativa H1: σ2 > 2, al livello di
significatività 0,01;
•
quali ipotesi devono essere soddisfatte per condurre i test di cui ai punti precedenti?
12) In base all’esperienza passata, si ritiene che il numero di imperfezioni al metro in un rotolo di
carta assorbente segua la legge di Poisson, con un valore atteso di una imperfezione ogni 5 metri di
carta (0,2 al metro). Calcolare:
•
la probabilità che in un metro di carta ci siano al più 2 imperfezioni;
•
la probabilità che in due metri di carta ci sia almeno una imperfezione;
•
la probabilità che in 50 metri di carta ci sia un numero di imperfezioni compreso tra 5 e
15 (estremi inclusi).
13) Un produttore di oggetti in plastica intende valutare la resistenza di blocchi rettangolari in
plastica da arredamento. Per un campione di 50 blocchi si calcolano i valori di un indice di solidità
riportati nel file “plastic.txt”.
•
Per un livello di significatività uguale a 0.05, si può ritenere che il valore medio
dell’indice sia diverso da 260?
•
Quali ipotesi devono essere soddisfatte per condurre un test di questo genere?
•
Calcolare il p-value e spiegarne il significato.
108
SOLUZIONI ESERCIZI MODULO 1
1)
> data(chickwts)
> z<-chickwts
> attach(z)
> x<-feed
> y<-weight
> str(x)
Factor w/ 6 levels "casein","horseb..",..: 2 2 2 2 2 2 2 2 2 2 ...
> class(x)
[1] "factor"
> sort(y)
[1] 108 124 136 140 141 143 148 153 158 160 168 169 171 179 181 193 199 203 206
[20] 213 216 217 222 226 227 229 230 242 243 244 248 248 250 257 257 258 260 260
[39] 263 267 271 271 283 295 297 303 309 315 316 318 318 320 322 325 327 329 332
[58] 334 339 340 341 344 352 359 368 379 380 390 392 404 423
> e<-seq(100,450,50)
> y2<-cut(y,breaks=e)
> y2
[1] (150,200] (150,200] (100,150] (200,250] (200,250] (150,200] (100,150]
[8] (100,150] (100,150] (100,150] (300,350] (200,250] (150,200] (100,150]
[15] (250,300] (200,250] (100,150] (150,200] (200,250] (250,300] (200,250]
[22] (250,300] (200,250] (200,250] (200,250] (300,350] (300,350] (200,250]
[29] (150,200] (250,300] (300,350] (250,300] (150,200] (150,200] (150,200]
[36] (200,250] (400,450] (300,350] (350,400] (300,350] (300,350] (200,250]
[43] (300,350] (250,300] (300,350] (300,350] (250,300] (300,350] (300,350]
[50] (250,300] (300,350] (300,350] (350,400] (150,200] (250,300] (200,250]
[57] (200,250] (300,350] (250,300] (350,400] (350,400] (350,400] (250,300]
[64] (400,450] (300,350] (350,400] (350,400] (200,250] (200,250] (250,300]
[71] (300,350]
7 Levels: (100,150] (150,200] (200,250] (250,300] (300,350] ... (400,450]
> tabella<-table(x,y2)
> tabella
y2
x
(100,150]
(150,200]
(200,250]
(250,300]
(300,350]
casein
0
0
2
2
2
horsebean
5
3
2
0
0
linseed
2
2
4
3
1
meatmeal
0
1
2
3
4
soybean
0
4
5
2
3
sunflower
0
0
1
2
7
y2
x
(350,400]
(400,450]
casein
5
1
horsebean
0
0
linseed
0
0
meatmeal
1
0
109
soybean
sunflower
0
1
0
1
# distribuzioni marginali
> xt<-margin.table(tabella,1)
> yt<-margin.table(tabella,2)
> xt
x
casein horsebean linseed meatmeal soybean sunflower
12
10
12
11
14
12
> yt
y2
(100,150] (150,200] (200,250] (250,300] (300,350] (350,400] (400,450]
7
10
16
12
17
7
2
# distribuzione condizionata
> tabella[4,]
(100,150] (150,200] (200,250] (250,300] (300,350] (350,400] (400,450]
0
1
2
3
4
1
0
> summary(tabella)
Number of cases in table: 71
Number of factors: 2
Test for independence of all factors:
Chisq = 65.61, df = 30, p-value = 0.0001829
Chi-squared approximation may be incorrect
> maxX2<-71*min(6-1,7-1)
> 65.61/maxX2
[1] 0.1848169
> quantile(y)
0% 25% 50% 75% 100%
108.0 204.5 258.0 323.5 423.0
> plot(x)
# oppure
> pie(table(X))
2)
> z<-scan("azioni.txt")
Read 150 items
>z
[1] 6.88 1.00 0.75 1.00 3.88 1.00 4.12 1.00 11.88 1.00 15.88 1.00
[13] 16.50 1.00 8.75 1.00 9.25 1.00 7.50 1.00 5.38 1.00 14.38 1.00
[25] 2.50 1.00 4.88 1.00 6.38 1.00 33.62 1.00 4.88 1.00 9.00 1.00
[37] 2.00 1.00 20.00 1.00 14.25 1.00 4.00 1.00 15.25 1.00 2.38 1.00
[49] 49.50 1.00 36.50 2.00 23.50 2.00 8.25 2.00 57.50 2.00 27.12 2.00
[61] 3.75 2.00 25.00 2.00 15.50 2.00 36.12 2.00 6.00 2.00 9.12 2.00
110
[73] 33.28 2.00 22.50 2.00 8.75 2.00 8.62 2.00 5.75 2.00 21.88 2.00
[85] 6.12 2.00 25.00 2.00 15.88 2.00 24.00 2.00 10.88 2.00 18.75 2.00
[97] 53.88 2.00 20.38 2.00 26.00 2.00 19.00 2.00 46.00 2.00 23.50 2.00
[109] 22.62 2.00 12.88 2.00 5.50 2.00 37.50 2.00 9.88 2.00 59.12 2.00
[121] 35.25 2.00 20.62 2.00 24.00 2.00 80.50 2.00 29.38 2.00 3.75 2.00
[133] 64.75 2.00 14.25 2.00 46.38 2.00 4.75 2.00 25.00 2.00 35.00 2.00
[145] 9.00 2.00 12.38 2.00 31.00 2.00
> A<-matrix(z,ncol=2,byrow=TRUE)
>A
[,1] [,2]
[1,] 6.88 1
[2,] 0.75 1
[3,] 3.88 1
[4,] 4.12 1
[5,] 11.88 1
[6,] 15.88 1
[7,] 16.50 1
[8,] 8.75 1
[9,] 9.25 1
[10,] 7.50 1
[11,] 5.38 1
[12,] 14.38 1
[13,] 2.50 1
[14,] 4.88 1
[15,] 6.38 1
[16,] 33.62 1
[17,] 4.88 1
[18,] 9.00 1
[19,] 2.00 1
[20,] 20.00 1
[21,] 14.25 1
[22,] 4.00 1
[23,] 15.25 1
[24,] 2.38 1
[25,] 49.50 1
[26,] 36.50 2
[27,] 23.50 2
[28,] 8.25 2
[29,] 57.50 2
[30,] 27.12 2
[31,] 3.75 2
[32,] 25.00 2
[33,] 15.50 2
[34,] 36.12 2
[35,] 6.00 2
[36,] 9.12 2
[37,] 33.28 2
[38,] 22.50 2
111
[39,] 8.75 2
[40,] 8.62 2
[41,] 5.75 2
[42,] 21.88 2
[43,] 6.12 2
[44,] 25.00 2
[45,] 15.88 2
[46,] 24.00 2
[47,] 10.88 2
[48,] 18.75 2
[49,] 53.88 2
[50,] 20.38 2
[51,] 26.00 2
[52,] 19.00 2
[53,] 46.00 2
[54,] 23.50 2
[55,] 22.62 2
[56,] 12.88 2
[57,] 5.50 2
[58,] 37.50 2
[59,] 9.88 2
[60,] 59.12 2
[61,] 35.25 2
[62,] 20.62 2
[63,] 24.00 2
[64,] 80.50 2
[65,] 29.38 2
[66,] 3.75 2
[67,] 64.75 2
[68,] 14.25 2
[69,] 46.38 2
[70,] 4.75 2
[71,] 25.00 2
[72,] 35.00 2
[73,] 9.00 2
[74,] 12.38 2
[75,] 31.00 2
> x<-A[1:25,1]
> y<-A[26:75,1]
>x
[1] 6.88 0.75 3.88 4.12 11.88 15.88 16.50 8.75 9.25 7.50 5.38 14.38
[13] 2.50 4.88 6.38 33.62 4.88 9.00 2.00 20.00 14.25 4.00 15.25 2.38
[25] 49.50
>y
[1] 36.50 23.50 8.25 57.50 27.12 3.75 25.00 15.50 36.12 6.00 9.12 33.28
[13] 22.50 8.75 8.62 5.75 21.88 6.12 25.00 15.88 24.00 10.88 18.75 53.88
[25] 20.38 26.00 19.00 46.00 23.50 22.62 12.88 5.50 37.50 9.88 59.12 35.25
[37] 20.62 24.00 80.50 29.38 3.75 64.75 14.25 46.38 4.75 25.00 35.00 9.00
[49] 12.38 31.00
> sort(x)
[1] 0.75 2.00 2.38 2.50 3.88 4.00 4.12 4.88 4.88 5.38 6.38 6.88
112
[13] 7.50 8.75 9.00 9.25 11.88 14.25 14.38 15.25 15.88 16.50 20.00 33.62
[25] 49.50
> sort(y)
[1] 3.75 3.75 4.75 5.50 5.75 6.00 6.12 8.25 8.62 8.75 9.00 9.12
[13] 9.88 10.88 12.38 12.88 14.25 15.50 15.88 18.75 19.00 20.38 20.62 21.88
[25] 22.50 22.62 23.50 23.50 24.00 24.00 25.00 25.00 25.00 26.00 27.12 29.38
[37] 31.00 33.28 35.00 35.25 36.12 36.50 37.50 46.00 46.38 53.88 57.50 59.12
[49] 64.75 80.50
> ist1<-hist(x,plot=FALSE)
> ist2<-hist(y,plot=FALSE)
> n1<-ist1$counts
> n1
[1] 16 7 0 1 1
> f1<-n1/length(x)
> p1<-f1*100
> p1
[1] 64 28 0 4 4
> sum(p1)
[1] 100
> n2<-ist2$counts
> n2
[1] 13 8 15 7 2 3 1 0 1
> f2<-n2/length(y)
> p2<-f2*100
> p2
[1] 26 16 30 14 4 6 2 0 2
> op<-par(mfrow=c(2,1))
> hist(x)
> hist(y)
> par(op)
> cumsum(n1)
[1] 16 23 23 24 25
> cumsum(f1)
[1] 0.64 0.92 0.92 0.96 1.00
> cumsum(p1)
[1] 64 92 92 96 100
> cumsum(n2)
[1] 13 21 36 43 45 48 49 49 50
> cumsum(f2)
[1] 0.26 0.42 0.72 0.86 0.90 0.96 0.98 0.98 1.00
> cumsum(p2)
[1] 26 42 72 86 90 96 98 98 100
> median(x)
[1] 7.5
> mean(x)
[1] 10.9516
> sqrt(var(x)*(length(x)-1)/length(x))
[1] 10.61805
113
> median(y)
[1] 22.56
> mean(y)
[1] 24.4408
> sqrt(var(y)*(length(y)-1)/length(y))
[1] 17.0957
> cvx<-10.61805/10.9516
> cvx
[1] 0.9695433
> cvy<-17.0957/24.4408
> cvy
[1] 0.6994738
> boxplot(x)
> boxplot(y)
3)
> z<-read.table("funds.txt",header=TRUE)
> attach(z)
> table(A)
A
GI IL MC SC TK
43 31 17 32 17
> table(A)/length(A)
A
GI
IL
MC
SC
TK
0.3071429 0.2214286 0.1214286 0.2285714 0.1214286
> table(A)/length(A)*100
A
GI
IL
MC
SC
TK
30.71429 22.14286 12.14286 22.85714 12.14286
> # moda: GI
> gini<-function(x) {
+ n<-length(x)
+ f<-table(x)/n
+ k<-length(f)
+ if(k==1)
+ return(0)
+ 1-sum(f^2)
+}
> gini(A)
[1] 0.774898
> plot(A)
> hist(E,plot=FALSE)
$breaks
114
[1] -0.00000045 0.50000045 1.00000045 1.50000045 2.00000045 2.50000045
[7] 3.00000045 3.50000045 4.00000045 4.50000045
$counts
[1] 4 36 48 30 17 4 0 0 1
$intensities
[1] 0.05714275 0.51428571 0.68571429 0.42857143 0.24285714 0.05714286 0.00000000
[8] 0.00000000 0.01428571
$density
[1] 0.05714275 0.51428571 0.68571429 0.42857143 0.24285714 0.05714286 0.00000000
[8] 0.00000000 0.01428571
$mids
[1] 0.2500000 0.7500004 1.2500004 1.7500004 2.2500004 2.7500004 3.2500004
[8] 3.7500004 4.2500004
$xname
[1] "E"
$equidist
[1] TRUE
attr(,"class")
[1] "histogram"
> hist(E)
> beta1<-function(x) {
+ n<-length(x)
+ s3<-sqrt(var(x)*(n-1)/n)^3
+ mx<-mean(x)
+ m3<-sum((x-mx)^3)/n
+ m3/s3
+}
>
> beta1(E)
[1] 0.8937315
> covCD<-cov(C,D)*(length(C)-1)/length(C)
> covCD
[1] 144.1959
4)
x<-scan("tax.txt")
> sort(x)
[1] 5.3 6.5 6.7 7.3 7.5 7.6 7.8 8.0 8.4 8.6 8.7 8.9 9.0 9.2 9.3
[16] 9.3 9.5 9.6 9.8 9.9 10.0 10.0 10.1 10.2 10.3 10.3 10.4 10.5 10.5 10.6
[31] 10.7 11.0 11.1 11.1 11.1 11.2 11.5 11.6 11.6 11.8 12.5 12.5 12.5 12.7 12.8
115
[46] 12.9 13.0 13.0 14.5 15.1
> n<-hist(x,plot=FALSE)
>n
$breaks
[1] 4 6 8 10 12 14 16
$counts
[1] 1 7 14 18 8 2
$intensities
[1] 0.009999984 0.070000000 0.140000000 0.180000000 0.080000000 0.020000000
$density
[1] 0.009999984 0.070000000 0.140000000 0.180000000 0.080000000 0.020000000
$mids
[1] 5 7 9 11 13 15
$xname
[1] "x"
$equidist
[1] TRUE
attr(,"class")
[1] "histogram"
> freqass<-n$counts
> freqass
[1] 1 7 14 18 8 2
> hist(x)
> freqrel<-freqass/50
> freqrel
[1] 0.02 0.14 0.28 0.36 0.16 0.04
> cumsum(freqass)
[1] 1 8 22 40 48 50
> cumsum(freqrel)
[1] 0.02 0.16 0.44 0.80 0.96 1.00
> summary(x)
Min. 1st Qu. Median Mean 3rd Qu. Max.
5.30 9.05 10.30 10.28 11.58 15.10
> var<-var(x)*(length(x)-1)/length(x)
> sqm<-sqrt(var)
> sqm
[1] 2.024451
> beta1<-function(x) {
116
+ n<-length(x)
+ s3<-sqrt(var(x)*(n-1)/n)^3
+ mx<-mean(x)
+ m3<-sum((x-mx)^3)/n
+ m3/s3
+}
> beta1(x)
[1] -0.04984544
> beta2<-function(x) {
+ n<-length(x)
+ s4<-sqrt(var(x)*(n-1)/n)^4
+ mx<-mean(x)
+ m4<-sum((x-mx)^4)/n
+ m4/s4
+}
> beta2(x)
[1] 2.920024
> boxplot(x)
5)
> z<-read.table("aaupdat.txt",header=TRUE)
> attach(z)
> pie(table(D))
> quantile(E)
0% 25% 50% 75% 100%
0 428 498 594 1009
> quantile(F)
0% 25% 50% 75% 100%
0 362 410 460 733
> quantile(G)
0% 25% 50% 75% 100%
0 311 348 387 576
> quantile(H)
0% 25% 50% 75% 100%
232 352 407 475 866
> boxplot(E,F,G,H)
> cov(E,I)*(length(E)-1)/length(E)
[1] 35595.42
> cor(E,I)
[1] 0.9948979
> hist(E,plot=FALSE)
$breaks
[1] 0 100 200 300 400 500 600 700 800 900 1000 1100
117
$counts
[1] 68 0 7 135 385 294 181 71 14 5 1
$intensities
[1] 5.857019e-04 0.000000e+00 6.029285e-05 1.162791e-03 3.316107e-03
[6] 2.532300e-03 1.559001e-03 6.115418e-04 1.205857e-04 4.306632e-05
[11] 8.613264e-06
$density
[1] 5.857019e-04 0.000000e+00 6.029285e-05 1.162791e-03 3.316107e-03
[6] 2.532300e-03 1.559001e-03 6.115418e-04 1.205857e-04 4.306632e-05
[11] 8.613264e-06
$mids
[1] 50 150 250 350 450 550 650 750 850 950 1050
$xname
[1] "E"
$equidist
[1] TRUE
attr(,"class")
[1] "histogram"
> hist(E)
6)
> data(cars)
> attach(cars)
> help(cars)
> x<-speed
> y<-dist
> plot(x,y)
> mx<-mean(x)
> my<-mean(y)
> n<-length(x)
> varx<-sum(x^2)/n-mx^2
> vary<-sum(y^2)/n-my^2
> cov<-sum(x*y)/n-mx*my
> b<-cov/varx
> a<-my-b*mx
> abline(a,b)
>a
[1] -17.57909
>b
[1] 3.932409
> sx<-sqrt(varx)
118
> sy<-sqrt(vary)
> r<-cov/(sx*sy)
>r
[1] 0.8068949
> ystim<-a+b*x
> res<-y-ystim
> devres<-sum(res^2)
> devy<-vary*n
> R2<-1-devres/devy
> R2
[1] 0.6510794
# oppure
> retta<-lm(y~x)
> summary(retta)
Call:
lm(formula = y ~ x)
Residuals:
Min 1Q Median 3Q Max
-29.069 -9.525 -2.272 9.215 43.201
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -17.5791 6.7584 -2.601 0.0123 *
x
3.9324 0.4155 9.464 1.49e-12 ***
--Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1
Residual standard error: 15.38 on 48 degrees of freedom
Multiple R-Squared: 0.6511, Adjusted R-squared: 0.6438
F-statistic: 89.57 on 1 and 48 DF, p-value: 1.490e-12
7)
# eliminare dal file di dati le righe di commento
> z<-read.table("water.txt",header=TRUE)
> attach(z)
> x<-Pressure
> y<-BPt
> plot(x,y)
> mx<-mean(x)
> my<-mean(y)
> n<-length(x)
> varx<-sum(x^2)/n-mx^2
> vary<-sum(y^2)/n-my^2
> cov<-sum(x*y)/n-mx*my
> b<-cov/varx
> a<-my-b*mx
119
>a
[1] 155.2965
>b
[1] 1.901784
> abline(a,b)
> sx<-sqrt(varx)
> sy<-sqrt(vary)
> r<-cov/(sx*sy)
>r
[1] 0.9972102
> ystim<-a+b*x
> res<-y-ystim
> devres<-sum(res^2)
> devy<-vary*n
> R2<-1-devres/devy
> R2
[1] 0.9944282
# oppure:
> retta<-lm(y~x)
> summary(retta)
Call:
lm(formula = y ~ x)
Residuals:
Min
1Q Median
3Q Max
-1.22687 -0.22178 0.07723 0.19687 0.51001
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 155.29648 0.92734 167.47 <2e-16 ***
x
1.90178 0.03676 51.74 <2e-16 ***
--Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1
Residual standard error: 0.444 on 15 degrees of freedom
Multiple R-Squared: 0.9944, Adjusted R-squared: 0.9941
F-statistic: 2677 on 1 and 15 DF, p-value: < 2.2e-16
8)
# eliminare dal file di dati le righe di commento
> z<-read.table("hospital.txt",header=TRUE)
> attach(z)
> x<-Height
> y<-Pulse
> plot(x,y)
> mx<-mean(x)
> my<-mean(y)
120
> n<-length(x)
> varx<-sum(x^2)/n-mx^2
> vary<-sum(y^2)/n-my^2
> cov<-sum(x*y)/n-mx*my
> b<-cov/varx
> a<-my-b*mx
>a
[1] 46.90693
>b
[1] 0.2097740
> abline(a,b)
> sx<-sqrt(varx)
> sy<-sqrt(vary)
> r<-cov/(sx*sy)
>r
[1] 0.2182248
> ystim<-a+b*x
> res<-y-ystim
> devres<-sum(res^2)
> devy<-vary*n
> R2<-1-devres/devy
> R2
[1] 0.04762205
> retta<-lm(y~x)
> summary(retta)
Call:
lm(formula = y ~ x)
Residuals:
Min 1Q Median 3Q Max
-16.666 -4.876 -1.520 3.424 33.012
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 46.9069 22.8793 2.050 0.0458 *
x
0.2098 0.1354 1.549 0.1279
--Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1
Residual standard error: 8.811 on 48 degrees of freedom
Multiple R-Squared: 0.04762, Adjusted R-squared: 0.02778
F-statistic: 2.4 on 1 and 48 DF, p-value: 0.1279
9)
> z<-read.table("ring.txt")
> attach(z)
> x<-V1
> y<-V2
121
> plot(x,y)
> retta<-lm(y~x)
> retta
Call:
lm(formula = y ~ x)
Coefficients:
(Intercept)
x
-259.6
3721.0
> summary(retta)
Call:
lm(formula = y ~ x)
Residuals:
Min
1Q Median
3Q Max
-85.1586 -21.4483 -0.8688 18.9722 79.3697
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -259.63 17.32 -14.99 <2e-16 ***
x
3721.02 81.79 45.50 <2e-16 ***
--Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1
Residual standard error: 31.84 on 46 degrees of freedom
Multiple R-Squared: 0.9783, Adjusted R-squared: 0.9778
F-statistic: 2070 on 1 and 46 DF, p-value: < 2.2e-16
10)
> z<-read.table("phone.txt")
> attach(z)
> cor(V2,V3)
[1] -0.6656528
> # la risposta è SI
11)
>z<-read.table("rent.txt")
>attach(z)
>y<-V1
>x<-V2
>plot(x,y)
>n<-length(x)
>mx<-mean(x)
>my<-mean(y)
>varx<-(sum((x-mx)^2))/n
122
>cov<-sum((x-mx)*(y-my))/n
>b<-cov/varx
>a<-my-b*mx
> mx
[1] 1135.32
> my
[1] 1386.4
> varx
[1] 79989.9
> cov
[1] 85200.75
>a
[1] 177.1208
>b
[1] 1.065144
#retta di regressione:
> abline(a,b)
> yp<-a+b*1000
> yp
[1] 1242.265
> ystim<-a+b*x
# oppure
> predict(retta,data.frame(x=1000))
[1] 1242.265
> predict(retta)
1
2
3
4
5
6
7
8
1082.4931 1721.5795 1332.8020 1489.3781 941.8941 1758.8595 1387.1243 950.4153
9
10
11
12
13
14
15
16
922.7216 1195.3984 1348.7791 1545.8307 2291.4315 1635.3028 1428.6649 1481.9221
17
18
19
20
21
22
23
24
1503.2250 1518.1370 1402.0363 1131.4898 1626.7817 1284.8705 981.3045 1242.2647
25
1455.2935
> res<-y-ystim
> r<-cor(x,y)
>r
[1] 0.8500608
> R2<-r^2
> R2
[1] 0.7226034
123
SOLUZIONI ESERCIZI MODULO 2
1)
> x<-c(114,78,96,137,78,103,117,126,86,99,114,72,104,73,86)
> n<-length(x)
> mx<-mean(x)
> s2<-var(x)
> #lc<-0.95
> #a<-0.05
> li<-mx-qt(.975,n-1)*sqrt(s2/n)
> ls<-mx+qt(.975,n-1)*sqrt(s2/n)
> cat("(",li,":",ls,")\n")
( 87.76956 : 109.9638 )
# oppure
> t.test(x)
One Sample t-test
data: x
t = 19.1084, df = 14, p-value = 1.994e-11
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
87.76956 109.96377
sample estimates:
mean of x
98.86667
>X~N
2)
> m0<-675
> sqm<-75
> n<-30
> m<-625
> # H0:mu=m0
> # H1:mu<m0
> z<-(m-m0)/(sqm/sqrt(n))
>z
[1] -3.651484
> qnorm(.01)
[1] -2.326348
> pnorm(-3.651484)
[1] 0.0001303647
> rifiutiamo H0
3)
> dbinom(0,10,0.2)
124
[1] 0.1073742
> pbinom(2,10,0.2,lower.tail=FALSE)+dbinom(2,10,0.2)
[1] 0.6241904
> pbinom(2,10,0.2)
[1] 0.6777995
4)
> x<-c(31, 35, 36, 34, 40, 38, 68, 46, 28, 33, 21, 34, 30, 42, 20, 34, 63, 22, 38, 28)
# caricare la funzione "testvar" (cfr.par. 5.5.3)
> source("testvarianza.txt")
> var(x)
[1] 147.4184
> var0<-200
> testvar(x,var0,"less")
Ipotesi nulla => H0 : var = 200
Varianza campionaria: 147.4184 , statistica test: 14.00475
p-value: 0.2165857 , livello del test: 0.05
Quantile Chi-quadrato: 10.11701 con 19 gdl
Ipotesi alternativa => H1 : var < 200
Decisione: non si rifuta H0
5)
> X<-c(4,6)
> Y<-c(7,9,11,12)
> pXY<-matrix(rep(0,8),2,4)
> pXY
[,1] [,2] [,3] [,4]
[1,] 0 0 0 0
[2,] 0 0 0 0
> pXY[1,1]<-0.1
> pXY[1,2]<-0.1
> pXY[1,3]<-0.2
> pXY[1,4]<-0.1
> pXY[2,1]<-0.2
> pXY[2,2]<-0.1
> pXY[2,3]<-0.1
> pXY[2,4]<-0.1
> pXY
[,1] [,2] [,3] [,4]
[1,] 0.1 0.1 0.2 0.1
[2,] 0.2 0.1 0.1 0.1
> rownames(pXY)<-X
> colnames(pXY)<-Y
> pXY
7 9 11 12
4 0.1 0.1 0.2 0.1
6 0.2 0.1 0.1 0.1
> sum(pXY)
125
[1] 1
> #distribuzioni di probabilità marginali
> pX<-margin.table(pXY,1)
> pY<-margin.table(pXY,2)
> pX
4 6
0.5 0.5
> pY
7 9 11 12
0.3 0.2 0.3 0.2
> pX[1]*pY[1]
4
0.15
> # X e Y non sono stocasticamente indipendenti, poichè non è p(x,y)=p(x)p(y)
> EX<-sum(X*pX)
> EX
[1] 5
> varX<-sum((X-EX)^2*pX)
> varX
[1] 1
> EY<-sum(Y*pY)
> varY<-sum((Y-EY)^2*pY)
> Esum<-EX+EY
> covXY<-sum(X%o%Y*pXY)-EX*EY
> varsum<-varX+varY+2*covXY
> Esum
[1] 14.6
> varsum
[1] 4.04
6)
> x<-c(1150.25,1352.67,983.45,1365.11,942.71,1577.77,330.00,872.37,1126.57,1184.17,1046.35,
1110.50,1050.86,851.60,1459.56,1252.01,373.91,1047.40,1064.46,1018.23,996.92,941.96,767.37,
1598.57,1598.66,1343.29,1617.73,1300.76,1013.27,1402.59,1069.32,1108.94,1326.19,1074.86,
975.86)
> n<-length(x)
> mx<-mean(x)
> s2<-var(x)
> #lc<-0.95
> #a<-0.05
> li<-mx-qt(.975,n-1)*sqrt(s2/n)
> ls<-mx+qt(.975,n-1)*sqrt(s2/n)
> cat("(",li,":",ls,")\n")
( 1021.165 : 1224.334 )
# oppure:
> t.test(x)
One Sample t-test
126
data: x
t = 22.4611, df = 34, p-value = < 2.2e-16
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
1021.165 1224.334
sample estimates:
mean of x
1122.750
>X~N
7)
> p<-35/200
>p
[1] 0.175
> n<-200
> li<-p-qnorm(.95)*sqrt(p*(1-p)/n)
> ls<-p+qnorm(.95)*sqrt(p*(1-p)/n)
> cat("(",li,":",ls,")\n")
( 0.1308065 : 0.2191935 )
# oppure:
> x<-n*p
>x
[1] 35
> prop.test(x,n,corr=FALSE)
1-sample proportions test without continuity correction
data: x out of n, null probability 0.5
X-squared = 84.5, df = 1, p-value = < 2.2e-16
alternative hypothesis: true p is not equal to 0.5
95 percent confidence interval:
0.1286052 0.2336443
sample estimates:
p
0.175
> prop.test(x,n)
1-sample proportions test with continuity correction
data: x out of n, null probability 0.5
X-squared = 83.205, df = 1, p-value = < 2.2e-16
alternative hypothesis: true p is not equal to 0.5
95 percent confidence interval:
0.1264402 0.2363814
sample estimates:
127
p
0.175
> binom.test(x,n)
Exact binomial test
data: x and n
number of successes = 35, number of trials = 200, p-value = < 2.2e-16
alternative hypothesis: true probability of success is not equal to 0.5
95 percent confidence interval:
0.1250244 0.2348840
sample estimates:
probability of success
0.175
8)
> x<-scan("tea.txt")
Read 105 items
> mean(x)
[1] 5.51
> t.test(x,mu=5.5,alternative="g")
One Sample t-test
data: x
t = 0.9105, df = 104, p-value = 0.1823
alternative hypothesis: true mean is greater than 5.5
95 percent confidence interval:
5.491772 Inf
sample estimates:
mean of x
5.51
> # No, p-value>0.01
> t.test(x,conf.level=0.99)
One Sample t-test
data: x
t = 501.6919, df = 104, p-value = < 2.2e-16
alternative hypothesis: true mean is not equal to 0
99 percent confidence interval:
5.481182 5.538818
sample estimates:
mean of x
5.51
128
9)
> ppois(5,6)
[1] 0.4456796
> dpois(5,6)
[1] 0.1606231
> 1-ppois(4,6)
[1] 0.7149435
> dpois(4,6)+dpois(5,6)
[1] 0.2944758
10)
> p<-0.05
> n<-20
> M<-n*p
> var<-n*p*(1-p)
>M
[1] 1
> var
[1] 0.95
> # P(X=0)
> dbinom(0,n,p)
[1] 0.3584859
> # P(X>=2)
> 1-(dbinom(0,n,p)+dbinom(1,n,p))
[1] 0.2641605
> #oppure
> 1-pbinom(1,n,p)
[1] 0.2641605
> # P(X<=3)
> pbinom(3,n,p)
[1] 0.9840985
11)
> x<-scan("bank.txt")
Read 15 items
> mx<-mean(x)
> mx
[1] 4.286667
> m0<-5
> t.test(x,mu=m0,alternative="l")
One Sample t-test
data: x
129
t = -1.6867, df = 14, p-value = 0.05691
alternative hypothesis: true mean is less than 5
95 percent confidence interval:
-Inf 5.03157
sample estimates:
mean of x
4.286667
> # NO, p-value>0.05
> var0<-2
> var(x)
[1] 2.682995
> n <- length(x)
>n
[1] 15
> stat <-(n-1)*var(x)/var0
> stat
[1] 18.78097
> alpha<-0.01
> alpha
[1] 0.01
> soglia <-qchisq(1-alpha, df=n-1)
> soglia
[1] 29.14124
> # stat<soglia, non si rifuta H0
12)
l1<-0.2
> ppois(2,l1)
[1] 0.9988515
> l2<-l1*2
> 1-(ppois(1,l2)-dpois(1,l2))
[1] 0.3296800
> l3<-l1*50
> ppois(15,l3)-ppois(4,l3)
[1] 0.922007
13)
> x<-scan("plastic.txt")
Read 50 items
> mean(x)
[1] 267.64
> m0<-260
> t.test(x,mu=m0,alternative="g")
One Sample t-test
data: x
130
t = 2.2103, df = 49, p-value = 0.01589
alternative hypothesis: true mean is greater than 260
95 percent confidence interval:
261.8448 Inf
sample estimates:
mean of x
267.64
>X~N
> p-value=0.01589<0.05, quindi rifiutiamo H0
131