Sei sulla pagina 1di 40

Comandi "R"

Lezione 1

> runif(10) #runif estrae numeri casuali tra 0 e 1 da una distribuzione uniforme

> rnorm(100) # numeri causali con distribuzione normale

COME DEFINISCI UNA VIARIABILE

> x <- exp(3)+2^3+1.573


> # operatore di assegnazione: <-

> x <- x+1


> str(x) # str: tipo della variabile
num 30.7

COME DEFINISCI UN VETTORE

> # Vettori
> # l'operatore c() sta per concatenate
> v <- c(1,2,33)
> str(v)
num [1:3] 1 2 33

COME DEFINISCI UNA MATRICE (4 parametri in ordine: 1 “data”; 2 “nrow”; 3 “ncol”; 4 “


byrow”

> A <- matrix(c(-2,3,4,-3,2,4,0,1,1),3,3,byrow=T)

#T (VERO) in ordine per righe – (numero maggiore di 0); F (FALSO) in ordine per colonne

>A
          [,1] [,2] [,3]
[1,]      -2        3        4
[2,]      -3        2        4
[3,]        0        1        1
> A <- matrix(c(-2,3,4,-3,2,4,0,1,1),3,3,byrow=F)
>A
          [,1] [,2] [,3]
[1,]      -2      -3        0
[2,]        3        2        1
[3,]        4        4        1
> A <- matrix(c(-2,3,4,-3,2,4,ciao,1,1),3,3,byrow=F)

COME RIMUOVERE UNA VARIABILE


> # rm = remove
> rm(A)

DETERMINANTE

> det(A)
[1] 1

.MEDIA

> mean(A)
[1] 1.111111

Lezione 2

> runif(10,-1,1) #cambiare l'interavallo per l'estrazione di numeri causali --> di default è fra 0 e 1

> help(runif) #l'help serve per imparare ad utilizzare una funzionalità di R

DIGRESSIONE SUGLI SCRIPT CHE NON TI FARà MAI FARE


# mi sono creato uno script con il menu Archivio --> nuovo documento , dove ho scritto tre
comandi che poi eseguo selezionandoli e utilizzando il menu Composizione --> esegui.

# OPERATORI
> #operatori aritmetici

DEFINISCO LE VARIABILI
> x<-5
> y<-16

APPLICO GLI OPERATORI (SONO IN ROSSO) PER LE OPERAZIONI

> x+y # somma


> x-y # sottrazione
> x*y # moltiplicazione
> y/x # divisione
> y %% x # resto della divisione
> %/% serve invece per calcolare la parte intera della divisione.
> y^x # elevamento a potenza
> x**2 #x al quadrato

# operatori relazionali

> x < y # minore


[1] TRUE
> x>y # maggiore
> x <= y # minore uguale
> x == y # uguale
> x != y # != not equal to (diverso)

> # Operatori logici


> x <- c(TRUE,FALSE,0,6) # 0 == falso , altri numeri == vero (DA CUI LA STRINGA SOTTO)

>x
[1] 1 0 0 6

> y <- c(FALSE,TRUE,FALSE,FALSE)

> !y # logical not SAREBBE NON Y (CODICE BINARIO    NON 1 è 0)

[1]    TRUE FALSE    TRUE    TRUE

> x & y # E logico (sia x che y sono vere perché x e y sia vera)

[1] FALSE FALSE FALSE FALSE

> x | y # O logico

[1]    TRUE    TRUE FALSE    TRUE

> x && y #MAGGIOR PROPORZIONE DI VERE CON “E”

[1] FALSE

> x || y #MAGGIOR PROPORZIONE DI VERE CON “o”

[1] TRUE

> # Precedenza degli operatori


1 POTENZE
2 MOLTIPLICAZIONI E DIVISIONI
3 SOMME E SOTTRAZIONI

> # prima calcola le potenze


> #poi fa moltiplicazioni e divisioni (in ordine)
> # infine vengono fatte le sottrazioni e le soome
OPERAZIONI CON MATRICI

> # operiamo con le matrici


> A <- matrix(c(-2,3,4,-3,2,4,0,1,1),3,3,byrow=T)
> B <- matrix(nrow=2,ncol=3) # è possibile omettere la dichiarazione dei valori per la matrice,
in questo caso tutti i campi della matrice assumeranno valore NA (Not a Number) – CASO
PARTICOLARE

>B
          [,1] [,2] [,3]
[1,]      NA      NA      NA
[2,]      NA      NA      NA

> matrix(1,2,3,4) # se non indichiamo nulla

#1 rappresenta è il primo parametro (data) che viene riciclato per riempire la matrice
#2 il numero di righe
#3 il numero di colonna
#4 un numero diverso da 0, interpretato da R come TRUE per il quarto parametro

          [,1] [,2] [,3]


[1,]        1        1        1
[2,]        1        1        1

> matrix(3,4,data=c(1,2,3),T) # possiamo modificare l'ordine dei parametri, a patto di dichiara


il nome di ciò che non è dichiarato nell'ordine corretto. Tutti gli altri parametri sono accettati
nell'ordine che R si attende.

          [,1] [,2] [,3] [,4]


[1,]        1        2        3        1
[2,]        2        3        1        2
[3,]        3        1        2        3

> m<-matrix(c(1,33,0,2,-3,10),2,3,byrow=T)

> det(m)

    'x' deve essere una matrice quadrata (regola delle matrici)


>m
          [,1] [,2] [,3]
[1,]        1      33        0
[2,]        2      -3      10

> m2<-cbind(m,c(1 -1)) #comando per aggiungere una colonna


> m2
          [,1] [,2] [,3] [,4]
[1,]        1      33        0        0
[2,]        2      -3      10        0

> rbind(m2,c(6,2,4,9)) #comando per aggiungere una riga

          [,1] [,2] [,3] [,4]


[1,]        1      33        0        1
[2,]        2      -3      10      -1
[3,]        6        2        4        9

> b<-c(-3,0,1) #vettore (c STA SEMPRE PER “CONCATENATE”)

> # risolvere il sistema Ax=b

>A
          [,1] [,2] [,3]
[1,]      -2        3        4
[2,]      -3        2        4
[3,]        0        1        1

>b
[1] -3    0    1

> solve(A,b) #COMANDO PER RISOLVERE “solve()”


[1]    10 -13    14

> sol<- solve(A,b) #soluzione

> sol
[1]    10 -13    14

> A %*% sol # siccome sol è la soluzione di Ax=b il prodotto matriciale A%*%sol restituisce b
(approssimato molto precisamente) doppia % per riottenere il vettore

                            [,1]
[1,] -3.000000e+00
[2,] -7.105427e-15
[3,]    1.000000e+00

> A * sol # questo invece è il risultato della moltiplicazione elemento per elemento con
l'operatore *
          [,1] [,2] [,3]
[1,]    -20      30      40
[2,]      39    -26    -52
[3,]        0      14      14

>A
          [,1] [,2] [,3]
[1,]      -2        3        4
[2,]      -3        2        4
[3,]        0        1        1
> A[2,3] # per selezionare un valore
[1] 4

> A[,3] # selezionare tutti gli elementi di una colonna VIRGOLA


[1] 4 4 1

> A[3,] # selezionare tutti gli elementi di una riga VIRGOLA


[1] 0 1 1

#    se sovrascrivo il valore di una variabile, il vecchio valore viene perso a meno che non
venga salvato in una variabile ancillare
>y
[1] 1
> A[3] # omettendo la virgola, R eSTRAe il valore corrispondente come se se i valori fossero
inseriti in un vettore invece che una matrice (default colonna 1 per il vettore).
[1] 0
> A[4]

[1] 3
> ??'transpose' #doppio punoto di domanda per sapere qualcosa (tipo help)

Lezione 3:

# IF: SE LA CONDIZIONE è REALIZZATA, ALLORA ESEGUE I COMANDI DOPO LA


CONDIZIONE, SE LA CONDIZIONE NON è REALIZZATA QUELLI DOPO ELSE (sta per
sennò)
.
> if (2>3) 'ciao' else 'miao'
[1] "miao"

# SI NOTI CHE LA CONDIZIONE GENERA SEMPRE VALORI DI VERITA'.

# IF ACCETTA (ED ESEGUE) UN SOLO VALORE DI VERITà, IGNORA EVENTUALI ALTRI:


> if (c(T,F)) 'ciao' else 'miao'
[1] "ciao"
Warning message:
In if (c(T, F)) "ciao" else "miao" :
    la condizione la lunghezza > 1 e solo il primo elemento verrà utilizzato

# UNA VALIDA ALTERNATIVA è ifelse che esegue l'if per ognuno dei valori di verità generati
dalla condizione.
> # ifelse(vb,vt,vf)
> ifelse(c(T,F),'ciao','miao')
[1] "ciao" "miao"

# ESERCIZIO 1:
> #1:4 + exp(-2:2)
> 1:4 + exp(-2:2)
[1] 1.135335 2.367879 4.000000 6.718282 8.389056
Warning message:
In 1:4 + exp(-2:2) :
    longer object length is not a multiple of shorter object length
> -2:2
[1] -2 -1    0    1    2
> 1:4 # create a sequence
[1] 1 2 3 4

# Si, il riciclaggio è utilizzato, come vedete la formula genera 5 risultati.


# Come? riutilizza la sequenza 1:4 dal primo elemento. E' facile mostrare che:
> 1+exp(2)
[1] 8.389056
>

Lezione 4:
> # Lezione 4 - (Grafici 2d)
> # Esercizio 1
>
>    set.seed(123)

> x<-sample(-5:5,4)
> y<-sample(-2:2,4)

>    x
[1] -2    2    5    4
>y
[1]    2 -2 -1    0

> # per avere gli stessi numeri se avete una versione diversa
> x<-c(-2,2,5,4)
> y<-c(2,-2,-1,0)

> plot(x,y,xlab="i'm the C!",ylab="you are the y!",main="a few points")


#xlab nome asse x; main titolo

> points(c(2,5),c(-2,-1),t='l',lty=2) #linea tratteggiata tra i due punti (2,-2) e (5,-1).

> #potevo usare lines ma in questo modo mi tengo anche la possibità di manipolare i punti.

> lines(c(-2,4),c(2,0),lwd=3,col="red") # una digressione per mostrare un'altro tipo di riga (non
richiesta). Lty “tratteggiata”; col “COLORE”; lwd “spessore)

> text(-1,0,'A message for u') #testo per descrivere un punto in particolare

> arrows(3,1,4,0,angle=30) #per mettere freccia


> # per l'utilizzo di arrows è stato consultato l'help.
>
>
> # ESERCIZIO 2
>
> plot(x,y)
> abline(2,1) #plotto la linea di equazione y=2+1*x    abline: comando rett (PRIMO NUMERO
è IL TEMRINE NOTO; SECONDO NUMERO è IL COEFFICIENTE DI X)

PER CREare un poligono


> polygon(x,y, col="tomato3") # polygon crea un poligono con i vertici dati. notiamo il colore
particolare esprimibile ancora con testo

Per fare una legenda


> legend(3,2,"color is tomato3",pch=19) #3,2 posizione; color… è il colore, phc simbolo)

> # volendo colorare il punto della legenda del colore corretto (quello del poligono):
> legend(3,2,"color is tomato3",pch=19, col="tomato3")
>
>
> # ESERCIZIO 3:
>
> x<- runif(100,-1,1)
> y<- rnorm (100)

> plot(x,y)
> # come caratterizzare i quadranti? Beh... con condizioni logiche e relazionali
> Q1 <- x>0 & y >0 # primo quadrante
> Q2 <- x<0 & y >0 # secondo quadrante
> Q3 <- x<0 & y <0 # secondo quadrante
> Q4 <- x>0 & y <0 # quarto quadrante

> # Cosa contiene Q4?


> Q4
    [1] FALSE FALSE    TRUE    TRUE    TRUE    TRUE FALSE FALSE FALSE
[10] FALSE FALSE FALSE    TRUE FALSE    TRUE    TRUE FALSE FALSE
[19]    TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[28] FALSE FALSE FALSE FALSE FALSE FALSE FALSE    TRUE FALSE
[37]    TRUE FALSE FALSE    TRUE    TRUE FALSE FALSE FALSE FALSE
[46] FALSE    TRUE FALSE    TRUE    TRUE FALSE FALSE FALSE    TRUE
[55]    TRUE FALSE FALSE FALSE FALSE    TRUE FALSE FALSE FALSE
[64]    TRUE FALSE FALSE FALSE FALSE FALSE    TRUE    TRUE FALSE
[73] FALSE FALSE FALSE    TRUE FALSE FALSE FALSE FALSE FALSE
[82] FALSE    TRUE FALSE FALSE    TRUE FALSE    TRUE FALSE FALSE
[91] FALSE FALSE FALSE FALSE FALSE    TRUE    TRUE FALSE    TRUE
[100] FALSE

# Stampiamo i punti nei diversi quadranti di diversi colori:


> points(x[Q1],y[Q1],pch=19,col=1)
> points(x[Q2],y[Q2],pch=19,col=2)
> points(x[Q3],y[Q3],pch=19,col=3)
> points(x[Q4],y[Q4],pch=19,col=4)
> # ecco perché vengono comode le codifiche numeriche dei colori!
> # si noti che in ognuna delle chiamate a points vengono plottati soltanto i punti per cui Qx
ha il valore True.
>
>
> # Esercizio 4
>
> f<-function(x) x**2 -x # prima definisco la funzione f come suggerito
> g<- function(x) -x**2 +x # poi definisco la funzione g come suggerito
> curve(f,0,1,lty=2, xlab='x',ylab='x^2-x',ylim=c(-1,1)) # poi plotto la prima curva (ovviamente
una parabola). #in verde intervallo di grafico visualizzato sull’asse x

> curve(g,0,1,lty=2,add=T) # poi plotto la seconda, ma ricordandomi che voglio aggiungere


una curva ad un grafico e non crearne uno nuovo, quindi utilizzo il parametro add=T    per
aggiungere la curva allo stesso grafico di prima

Lezione 5:
> # Definisco una funzione g, di due variabili x e y
> g<- function(x,y) x^2 +y^2 -2*x +3*y-1

> # per fare un grafico ho bisogno di 3 valori: x-value, y-value, z-value


> # x e y costituiscono i valori sugli assi per i quali la funzione è calcolata
> # z sono invece i valori che la funzione g assume per data tupla (x,y)

> # rivediamo la funzione g


>g
function(x,y) x^2 +y^2 -2*x +3*y-1
> # per generare un grafico (3d) di questa funzione genero innanzitutto una sequenza di
valori x:

> x<-seq(-3,3,len=31)
>x
[1] -3.0 -2.8 -2.6 -2.4 -2.2 -2.0 -1.8 -1.6 -1.4 -1.2 -1.0
[12] -0.8 -0.6 -0.4 -0.2    0.0    0.2    0.4    0.6    0.8    1.0    1.2
[23]    1.4    1.6    1.8    2.0    2.2    2.4    2.6    2.8    3.0
# e una sequenza di valori y:
> y<-seq(-3,3,len=31)
>y
[1] -3.0 -2.8 -2.6 -2.4 -2.2 -2.0 -1.8 -1.6 -1.4 -1.2 -1.0
[12] -0.8 -0.6 -0.4 -0.2    0.0    0.2    0.4    0.6    0.8    1.0    1.2
[23]    1.4    1.6    1.8    2.0    2.2    2.4    2.6    2.8    3.0
> # infine attraverso la funzione outer posso calcolare la zeta: valore della funzione z
> z<-outer(x,y,g)
> str(z)
num [1:31, 1:31] 14 12.44 10.96 9.56 8.24 ...
> # Come funziona outer (vedere anche help)?
> #dato un vettore di lunghezza m e un vettore di lunghezza n
> # calcola il outer product.
Genera una matrice di lunghezza mxn dove gli elementi della matrice sono:
A(i,j)=fun(X(i),Y(j))

Graifici 3d
> # un grafico di tipo Heatmap, tre input le x, le y e i valori della funzione (assegnati a
variabile z.
> image(x,y,z)

> # Sono naturalmente disponibili parametri, come quelli per cambiare la palette (tavolozza di
colori):
> image(x,y,z,col= rainbow(12))

Persp genera grafici di tipo prospettiva

> persp(x,y,z) # prospettiva

> persp(x,y,z,phi=30,theta=3) # è possibile variare l'altezza del punto di osservazione (phi o


co-latitudine) e la direzione azimutinale (i.e dell'azimut, col il parametro theta, spostando la
visualizzazione a sinistra o destra.
> persp(x,y,z,phi=30,theta=30) # un altro esempio
> persp(x,y,z,phi=30,theta=30,tick="detailed") # introduciamo anche i valori di x,y e z sugli
assi.
Il grafico a curve o linee di livello:

> contour(x,y,z) # linee di livello

> grid(col=1) # è utile utilizzarlo insieme al comando di basso livello grid


> g(2,1) # per esempio per avere un'idea del valore di massima della funzione di un
determinato punto. come in questo esempio.
[1] 3

unire più grafici 3d,    comandi a basso livello e aggiungendo add=T


> image(x,y,z) # prima mi genero la mappa di colore
> contour(x,y,z,add=T) # poi complemento con le linee di livello.

# Caricare un dataframe da fonte esterna

> d<-read.table("http://virgo.unive.it/paolop/papers/grades.txt")
> str(d)
'data.frame':167 obs. of    1 variable:
$ V1: Factor w/ 53 levels "-1","-1.5","0",..: 53 17 41 41 38 22 11 34 33 35 ...
# R non ha riconosciuto che il primo valore era il titolo della variabile (header)
# Per esplicitare la presenza di un header:
> d<-read.table("http://virgo.unive.it/paolop/papers/grades.txt",header=T)
> str(d)
'data.frame':166 obs. of    1 variable:
$ grade: num    16 28.5 28.5 26.5 18.5 13 24 23.5 24.5 3 ...
> d$grade
    [1] 16.0 28.5 28.5 26.5 18.5 13.0 24.0 23.5 24.5    3.0 11.0
[12] 16.0 16.5 15.5 24.0 22.5 31.0 31.0 18.5    8.5 17.0 18.5
[23] 29.0 26.5 14.5 28.5 18.0 31.0 13.5 29.0 18.0 25.0 21.0
[34] 13.0 12.5 31.0 -1.0 31.0    3.5 24.0 22.0 31.0    9.5 26.0
[45] 19.5 13.5    9.5 17.0 31.0 26.5 22.0 23.5 19.5 31.0 31.0
[56] 26.5 28.5 12.5 26.0 28.0 24.5    0.0 16.5    4.5 24.0 28.5
[67] 12.0 24.0 29.0    5.0 24.0 20.5    4.5 13.0 -1.0 18.5 31.0
[78] 15.0 31.0 11.0    5.0 26.0 20.0 29.0 18.0 18.0 31.0    7.5
[89] 14.0 24.0 19.0    0.0 31.0 26.0 22.0 26.0 10.0 11.5 15.5
[100] 24.0 24.0 -1.5 26.0 23.5 18.0 23.5 21.0 17.5    5.0 18.0
[111] 14.5    8.5 10.5 18.5 15.0 16.5    3.0 23.5 13.5    1.5 24.5
[122] 21.5 26.5 26.0 14.5 31.0 31.0    2.5    3.0 24.0 24.0 15.5
[133] 24.0 26.5 28.5 10.0 10.5 29.0 17.5 22.0 15.0 12.5 19.5
[144] 22.0 10.5 28.5 31.0 28.5    8.5 31.0 18.5 16.5 26.0 13.0
[155] 27.0 31.0 17.0 22.0    9.0    2.0    5.5    4.5 22.0 26.5 31.0
[166] 29.0

> sum(d$grade>=18) # Quanti sono i voti maggiori di 18?


[1] 100
> d$grade>=18
    [1] FALSE    TRUE    TRUE    TRUE    TRUE FALSE    TRUE    TRUE    TRUE
[10] FALSE FALSE FALSE FALSE FALSE    TRUE    TRUE    TRUE    TRUE
[19]    TRUE FALSE FALSE    TRUE    TRUE    TRUE FALSE    TRUE    TRUE
[28]    TRUE FALSE    TRUE    TRUE    TRUE    TRUE FALSE FALSE    TRUE
[37] FALSE    TRUE FALSE    TRUE    TRUE    TRUE FALSE    TRUE    TRUE
[46] FALSE FALSE FALSE    TRUE    TRUE    TRUE    TRUE    TRUE    TRUE
[55]    TRUE    TRUE    TRUE FALSE    TRUE    TRUE    TRUE FALSE FALSE
[64] FALSE    TRUE    TRUE FALSE    TRUE    TRUE FALSE    TRUE    TRUE
[73] FALSE FALSE FALSE    TRUE    TRUE FALSE    TRUE FALSE FALSE
[82]    TRUE    TRUE    TRUE    TRUE    TRUE    TRUE FALSE FALSE    TRUE
[91]    TRUE FALSE    TRUE    TRUE    TRUE    TRUE FALSE FALSE FALSE
[100]    TRUE    TRUE FALSE    TRUE    TRUE    TRUE    TRUE    TRUE FALSE
[109] FALSE    TRUE FALSE FALSE FALSE    TRUE FALSE FALSE FALSE
[118]    TRUE FALSE FALSE    TRUE    TRUE    TRUE    TRUE FALSE    TRUE
[127]    TRUE FALSE FALSE    TRUE    TRUE FALSE    TRUE    TRUE    TRUE
[136] FALSE FALSE    TRUE FALSE    TRUE FALSE FALSE    TRUE    TRUE
[145] FALSE    TRUE    TRUE    TRUE FALSE    TRUE    TRUE FALSE    TRUE
[154] FALSE    TRUE    TRUE FALSE    TRUE FALSE FALSE FALSE FALSE
[163]    TRUE    TRUE    TRUE    TRUE
> #Estrarre i voti maggiori di 18?
> promossi<-d$grade[d$grade>=18]
> promossi
    [1] 28.5 28.5 26.5 18.5 24.0 23.5 24.5 24.0 22.5 31.0 31.0
[12] 18.5 18.5 29.0 26.5 28.5 18.0 31.0 29.0 18.0 25.0 21.0
[23] 31.0 31.0 24.0 22.0 31.0 26.0 19.5 31.0 26.5 22.0 23.5
[34] 19.5 31.0 31.0 26.5 28.5 26.0 28.0 24.5 24.0 28.5 24.0
[45] 29.0 24.0 20.5 18.5 31.0 31.0 26.0 20.0 29.0 18.0 18.0
[56] 31.0 24.0 19.0 31.0 26.0 22.0 26.0 24.0 24.0 26.0 23.5
[67] 18.0 23.5 21.0 18.0 18.5 23.5 24.5 21.5 26.5 26.0 31.0
[78] 31.0 24.0 24.0 24.0 26.5 28.5 29.0 22.0 19.5 22.0 28.5
[89] 31.0 28.5 31.0 18.5 26.0 27.0 31.0 22.0 22.0 26.5 31.0
[100] 29.0
> # estrarre i voti tra 22 e 26
> piudi22<- d2$grade>=22
> menodi26 <- d2$grade<=26
> tra22e26 <- d$grade[menodi26 & piudi22]
> tra22e26
[1] 24.0 23.5 24.5 24.0 22.5 25.0 24.0 22.0 26.0 22.0 23.5
[12] 26.0 24.5 24.0 24.0 24.0 26.0 24.0 26.0 22.0 26.0 24.0
[23] 24.0 26.0 23.5 23.5 23.5 24.5 26.0 24.0 24.0 24.0 22.0
[34] 22.0 26.0 22.0 22.0
> hist(tra22e26)
> hist(d$grade) # Istogramma della funzione

# set.seed blocca il generatore di numeri casuali per avere sempre le stesse sequenze di
valori casuali.

> set.seed(123)
> x<- sample(-5:5,4)
>x
[1] -2    2    5    4

Lezione 6:

> # Esercizio 1
> f<- function(x) x^4-3*x**3-3*x^2-3*x-2 # creo la funzione f
> curve(f,-10,10) # faccio esperimenti per visualizzarla al meglio
> curve(f,-5,5, ylim=c(-50,100))
> grid(col=4) # una griglia rende più chiari i punti chiave
> abline(h=0,col=2) # per chiarire dove la funzione assume valore zero, disegno linea
orizziontare,
# ho due soluzioni una tra -2 e 0 e una tra 2 e 5

> uniroot(f,c(-2,0)) # posso trovare la prima soluzione cosi:

$root # la soluzione del problma


[1] -0.7213881

$f.root # il valore della funzione alla soluzione


[1] 1.185705e-05

$iter # numero di iterazioni svolte


[1] 8

$init.it # questo è un place-holder per cose che potrebbero essere aggiunte in futuro agli
output della funzione
[1] NA

$estim.prec # precisione del processo.


[1] 6.103516e-05

Lezione 7:
> # ottimizzazione di funzioni di una variabile.

ottimizzare in un intervallo [a,b]


> f<-function(x) x^4 -3*x^3-3*x^2-3*x+2 # creo una nuova funzione
>f
function(x) x^4 -3*x^3-3*x^2-3*x+2
> curve(f,-10,10) # faccio un poco di esperimenti per visualizzarla in modo correto

> # il comando optimize:


> # optimize(nomefunzione,intervallo)
> optimize(f,c(2,4))
$minimum
[1] 2.864946 # valore di x per cui c'è il minimo di questa funzione

$objective
[1] -34.39441 # valore al minimo della funzione obbiettivo.

> points(2.864946,-34.39441,pch=15,col=2) # visualizziamo il puto per conferma grafica

# Rimane in capo a noi indicare un intervallo dove un minimo esiste. In questo intervallo (-1,1)
esiste solo un minimizer (un minimizzatore) non un minimo:

> optimize(f,c(-1,1))
$minimum
[1] 0.999959

$objective
[1] -5.999426
> # per calcolare il massimo uso il comando maximum=T
> optimize(f,c(-1,0.5),maximum=T)
$maximum
[1] -0.9999415

$objective
[1] 5.999415

Non è possibile calcolare un massimo/minimo su un intervallo infinito


> optimize(f,maximum=T)
Error in optimize(f, maximum = T) :
    l'argomento "interval"    non è specificato e non ha un valore predefinito

# La forza e i limiti di optimize


> gg <- function(x) sin(x)+ abs(x/4) # definiamo una funzione
# esploriamola visualmente
> curve(gg,-10,10)
> curve(gg,-50,50)
> optimize(gg,c(-10,10)) # proviamo a cercare il minimo tra -10 e 10
$minimum
[1] -1.318105

$objective
[1] -0.6387168

> points(-1.318105,-0.6387168,pch=16,col=2) # il minimo è giusto!

Troppi minimi locali! Resta in capo a noi posizionarci in un intervallo tale da rendere a R
possibile calcolare il minimo.
> res<-optimize(gg,c(-10,10)) # possiamo assegnare il risultato di optimize ad una variabile
> res
$minimum
[1] -1.318105

$objective
[1] -0.6387168

> str(res) # res è una lista


List of 2
$ minimum    : num -1.32
$ objective: num -0.639
> points(res$minimum,res$objective,pch=16,col=5) # possiamo usare elementi della lista
direttamente col comando nomelista$nomeelementolista
> sss<-res$minimum
> sss
[1] -1.318105
> # Digressione sulle liste
> # ancora sulle liste
> vec<-c(1,2,3)

> char_vec<-c("a","b","c","d")
> logic_vec<- c(T,F,T)
> our_list<- list(vec, char_vec, logic_vec) # definire una lista
> our_list
[[1]]
[1] 1 2 3

[[2]]
[1] "a" "b" "c" "d"

[[3]]
[1]    TRUE FALSE    TRUE

> names(our_list)<- c("numeri","testo","logico") # assegnare un nome agli elementi della lista


> our_list
$numeri
[1] 1 2 3

$testo
[1] "a" "b" "c" "d"

$logico
[1]    TRUE FALSE    TRUE

>
> our_list$numeri
[1] 1 2 3
> altro caso: rifersi ad un elemento di uno dei vettori nella lista:
> our_list$testo[2]
[1] "b"

Lezione 8:
# Esercizio 1:
> f<- function(x,y) 5*x^2 + x*y+y^2-4*x+3*y-5    # definisco la funzione in R
>f
function(x,y) 5*x^2 + x*y+y^2-4*x+3*y-5
# mi preparo una visualizzazione per esplorare la natura di questa funzioen
> x<-seq(-3,3,length=31); y<-seq(-3,3,length=31)
> z<-outer(x,y,f)
> image(x,y,z)
> contour(x,y,z) # esploro vari tipi di visualizzazione
> fb<-function(x) f(x[1],x[2]) # definisco la funzione fb come funzione di una variabile vettoriale
e utilizzo la definizione di f per rendere più chiara e meno prona ad errori la definizione della
fb vettoriale.
> # come computare un valore della funzione fb vettoriale:
> f(1,2)   
[1] 8
> fb(1,2) # no!
Error in fb(1, 2) : unused argument (2)
>
> fb(c(1,2)) # Si.      Con fb uso il comando c
[1] 8
# posso finalmnete provare a minimizzare avendo intuito dall'analisi grafica dove si trova il
minimo e partendo da un punto di partenza adeguatamente vicino.
> optim(c(1,2),fb)
$par # coordinate del minimo
[1]    0.5788665 -1.7894556

$value    # valore della funzione al minimo


[1] -8.842105

$counts # numero di passaggi fatti


function gradient
            65              NA

$convergence # convergenza avvenuta =0 (con 1 ci sono dei problemi, quando appare


meglio verificare).
[1] 0

$message
NULL

> points(0.5788665,-1.7894556) # disegnamo il punto del minimo per verificare graficamente.

# Esercizio 2 (massimizziamo la stessa funzione)


> optim(c(1,2),fb,control=list(fnscale=-1))    Per massimizzare bisogna aggiungere il parametro
control=list(fnscale=-1)

> # Molti segni che qualcosa non va:


$par
[1] 5.368343e+55 9.992669e+54 # i valori del massimo sono enormi

$value
[1] 1.504585e+112 # il valore della funzione è corrispondentemente enorme...

$counts # sono stati esauriti tutte le iterazioni della ricerca disponibili


function gradient
          501              NA

$convergence # e la convergenza non è avvenuta


[1] 1
$message
NULL
# QUESTA FUNZIONE NON HA UN MASSIMO _FINITO_
# calcolo del massimo nell'intervallo [-3,3]x[-3,3].
# Chiaramente si trova ai margini dell'intervallo, esploriamo gli angoli:
> f(-3,-3)
[1] 61
> f(-3,3)
[1] 61
> f(3,3)
[1] 55
> f(3,-3)
[1] 19
> f(-3,3)==f(-3,-3) # confrontiamo gli angoli coi valori massimi per essere sicuri che siano
uguali
[1] TRUE
# il massimo (nell'intervallo [-3,3]x[-3,3], si trova a f(-3,3) e f(-3,-3) dove la funzioe assume
valore 61
# avrei naturamente potuto seguire un procedimento simile a quello di esercizio 5 qui sotto.
>

Lezione 9:

> fb<-function(x) f(x[1],x[2]) # Definisco la funzione in forma vettoriale per passarla a


constrOptim

> constrOptim(c(2,-2),fb,NULL,A,b) # posso infine chiamare constrOptim partendo da un


punto nel dominio e ricordandomi di passare la matrice A e il vettore b.
$par
[1]    1.4999881 -0.5000443 # coordinate del punto di minimo

$value
[1] -0.5 # valore della funzione al minimo

$counts
function gradient
          106              NA

$convergence
[1] 0

$message
NULL

$outer.iterations
[1] 3

$barrier.value
[1] -2.163737e-05

Lezione 10:

capire se un sistema lineare ha soluzioni o meno

> #Abbiamo bisogno del teorema di Rouche-Capelli, che è basato sul Rango (rank).
> #Utilizzeremo la funzione di R e in particolare il suo componente $rank.

> # qr()        $rank


#Consideriamo il sistema:
> # x+y=3
> # 2x+2y=6
> # Ha una soluzione?
> Possiamo trasformare i coefficienti e i termini noti in una matrice e un vettore
rispettivamente:
> A<-matrix(c(1,1,2,2),2,2,byrow=T)
>A
          [,1] [,2]
[1,]        1        1
[2,]        2        2
> b<-c(3,6)
>b
[1] 3 6
> qr(A)$rank # Calcolo il rango della matrice A
[1] 1
> #1 riga indipendente
> #la matrice a contiene solo una riga indipendente!
> # Infatti la seconda riga non è indipendente dalla prima: è semplicemente 2 volte la prima.
> # Ax = b
> In questo sistema vediamo 2 equazioni ma in realtà ce ne è una sola.
> # Abbiamo soluzioni per questo sistema    Ax=b?
> qr(cbind(A,b))$rank # Calcolo il rango della matrice completa
[1] 1
> # RC il sistema ha soluzioni! siccome i due ranghi sono uguali. r=1.
Quante soluzioni ho?
> # Inf^(n-r)=Inf^(2-1)=Inf^1
> #questo significa che abbiamo infinite soluzioni che dipendono da un parametro.
> # Ricordiamo il sistema e verifichiamo questa affermazione
> # x+y=3
> # 2x+2y=6
> # Queste alcune delle soluzioni:
> # x=0 y=3
> # x=-3 y=+6
> # In generale se noi prendiamo una equazione e la risolviamo per una delle due variabili
abbiamo la relazione tra le due variabili, che dipende appunto da un parametro.
> # x+y=3 --> y=3-x    --> se noi prendiamo un t
> #x=t, y=3-t
>

In alcuni casi (ad esempio matrici quadrate con determinante non zero), la soluzione può
essere calcolata utilizzando l’inverso della matrice.

> # Dato il sistema Ax=b, x=A^(-1) %*% b


> det(A)
[1] 1
> # si può usare questo metodo di soluzione
> # l'inverso di una matrice    A si calcola con solve(A):
> solve(A)
          [,1] [,2]
[1,]        3      -1
[2,]      -2        1
> solve(A) %*% b # calcolo la soluzione usando l'inversa della matrice A
          [,1]
[1,]      -4
[2,]        5
>
>
> # ESEMPIO 6: l'inversa generalizzata
# Riprendiamo l'esempio numero 3 qui sopra:
> A<- matrix(1:9,3,3,,byrow=T)
> b<-c(7,5,3)
#    Come abbiamo visto prima in questo caso ci sono infinite soluzioni. come possiamo
calcolarne 1?
> solve(A,b)
Error in solve.default(A, b) :
    il sistema è numericamente singolare: valore di condizione di reciprocità = 2.59052e-18
> # L’errore è dovuto all’eccesso di soluzioni (sono troppe!)
> # troveremo un tipo di inversa che può essere usata anche se ci sono tante soluzioni.
Intanto ci basti capire cosa significa il messaggio di errore:
> solve(A)
Error in solve.default(A) :
    il sistema è numericamente singolare: valore di condizione di reciprocità = 2.59052e-18
> # Significa che il determinante di A è praticamente zero (dal punto di vista computazionale)
e dunque non posso calcolarmi l’inversa.

> det(A) # Infatti il determinante è molto vicino a 0


[1] 6.661338e-16
>
> # Possiamo usare un trucco: possiamo usare una “inversa generalizzata”
> # Inversa generalizzata di Moore-Penrose
> # Si chiama ginv= generalized inverse che si può sempre calcolare ed è stata inventata da
Moore-Penrose
> help(ginv) # ginv non è disponibile in R di default
No documentation for ‘ginv’ in specified packages and libraries:
you could try ‘??ginv’
> ginv()
Error in ginv() : non trovo la funzione "ginv"
> library(MASS) # Per usare ginv,devi prima caricare una libreria che si chiama library(MASS)
> ginv(A) # Mentre solve(A) dava errore,    ginv(A) mostra l’inversa generalizzata.
                        [,1]                    [,2]                [,3]
[1,] -0.63888889 -1.666667e-01    0.30555556
[2,] -0.05555556    3.469447e-17    0.05555556
[3,]    0.52777778    1.666667e-01 -0.19444444
> ginv(A) %*% b    # per calcolare la soluzione del sistema (una soluzione)
                      [,1]
[1,] -4.3888889
[2,] -0.2222222
[3,]    3.9444444
> sol<- ginv(A) %*% b
> sol
                      [,1]
[1,] -4.3888889
[2,] -0.2222222
[3,]    3.9444444
> # sol risolve il problema Ax=b?
> A %*% sol
          [,1]
[1,]        7
[2,]        5
[3,]        3
> # Abbiamo verificato di avere una soluzione verificata (dato che A %*% sol = b).
>
> # Quando SAI che ci sono soluzioni puoi computarne 1 moltiplicando (in senso matriciale)
ginv(A) per il vettore b.
> # Definizione: Data una matrice A(nxm), una matrice G(mxn) è detta inversa generalizzata
di A se    A%*%G%*%A=A.

Appunti Lezione 10
qr(A)$rank # Calcolo il rango della matrice A
qr(cbind(A,b))$rank # Calcolo il rango della matrice completa
library(MASS) # Per usare ginv,devi prima caricare una libreria che si chiama library(MASS)
ginv(A) # Mentre solve(A) dava errore,    ginv(A) mostra l’inversa generalizzata. Che dà
sempre soluzione

Lezione 11:

> # State preference model


> # Modello di un mercato finanziario
> # Ci sono due periodi, ora (t=0) e il futuro (t=1)
> # n assets e stati del mondo
> # Incertezza sul futuro determinata dai payoff che sono contingenti allo stato del mondo.
>
> # Y matrix = la nostra economia (quella delle slides)
> Y <- matrix(c(104,104,104,108,102,100,112,106,93),3,3)
>Y
          [,1] [,2] [,3]
[1,]    104    108    112
[2,]    104    102    106
[3,]    104    100      93

# Un nuovo comando, ma utile.


#Posso aggiungere nomi alle colonne e alle righe, per poterle leggere in modo più semplice.

> colnames(Y) <- c("btp","azioni","azioni rischiose")


>Y
            btp azioni azioni rischiose
[1,]    104      108                  112
[2,]    104      102                  106
[3,]    104      100                    93
> rownames(Y) <- c("Stato buono","stato neutrale","stato negativo")
>Y
                                  btp azioni azioni rischiose
stato buono            104      108                  112
stato neutrale      104      102                  106
stato negativo      104      100                    93
>
> # Cos'è un portafoglio?
> # E' una combinazione di asset, ho bisogno di un un vettore di pesi (weights) per il
portafoglio.
> # pesi = quantità di asset
> # prendo il portafoglio medio: 1/3,1/3,1/3
pesi<-c(1/3,1/3,1/3)
> # Quale è il payoff di questo portafoglio?    Pesi* colonna dei payoffs
> 1/3*Y[,1]+1/3*Y[,2]+1/3*Y[,3]
> # o ancora meglio (sempre meglio sfruttare le variabili):
> pesi[3]*Y[,1]+pesi[3]*Y[,2]+pesi[3]*Y[,3]
    lucky state neutral state    gloomy state
                    108                      104                        99
                    
> # La precedente linea è un vettore di payoff. uno per ogni stato del mondo
>
> # Naturalmente i payoff di un portafoglio possono essere anche calcolati con il prodotto
matriciale Y %*% pesi
> Y %*% pesi
                            [,1]
lucky state        108
neutral state    104
gloomy state        99
> # dove pesi è un vettore di quantità (weights), in questo esempio, 1/3,1/3,1/3
>
> # Finora abbiamo parlato di payoff, ma non vi ho detto nulla sui costi!
>Y
                            bond stock risky stock
lucky state        104      108                  112
neutral state    104      102                  106
gloomy state      104      100                    93
> # Nelle slide abbiamo chiamato pigreco la funzione dei costi. Occhio che pi è una parola
riservata.. usiamo pai
> pi # this is "pi greco"
[1] 3.141593
> pai <- c(100,100,100) # questo vettore, pai, contiene i costi degli asset (cioè i costi delle mie
colonne)

> # Quanto costa il portafoglio medio discusso sopra?


> pai
[1] 100 100 100
> # dobbiamo solo calcolare il costo degli asset, moltiplicati per i pesi.
> sum(pai*pesi)
[1] 100
> Y %*% x    # abbiamo visto che i payoff per ogni stato del mondo sono dati da:
                            [,1]
lucky state        108
neutral state    104
gloomy state        99
>
> # Quindi acquistando ai prezzi pai, otteniamo un utile in tutti i gli stati del mondo meno il
peggiore.
>
> # replication: diciamo che un vettore b può essere replicato se c'è un portafoglio con gli
stessi ritorni
    # (payoff). In altre parole, b può essere replicato se c'è un x tale che Ax = b.
>
> # Vogliamo sapere se un payoff può essere replicato in una data una economia Y
    # (e per una dato vettore pai)
>
> #dato Y e pai
>Y
                            bond stock risky stock
lucky state        104      108                  112
neutral state    104      102                  106
gloomy state      104      100                    93
> pai
[1] 100 100 100

> # Posso replicare i payoff c(108,104,99)?


>
> # Per rispondere dobbiamo risolvere Yx=b dove b <- c(108,104,99)
> # Prima verifichiamo che esista una soluzione
> qr(Y)$rank # Calcoliamo il rango della matrice Y
[1] 3
>b
[1] 7 5 3
> b <- c(108,104,99) # definiamo i payoff come vettore
> qr(cbind(Y,b))$rank #calcoliamo il rango sulla matrice completa
[1] 3
> # Esistono soluzioni. Quante?
> # utilizzando il teorema RC: n=3 r=3 => infinity^(3-3)=infinity^0=1
> # una sola.
# In questo caso sappiamo che possiamo risolvere il problema Yx=b con solve.
> solve(Y,b) # Questo mi da i pesi che servono per replicare l'asset. Ovviamente:
              bond              stock risky stock
    0.3333333      0.3333333      0.3333333
> ginv(Y) %*% b # Possiamo farlo anche con l'inversa generalizzata
                    [,1]
[1,] 0.3333333
[2,] 0.3333333
[3,] 0.3333333
>

Lezione 12:

# Proviamo a definire un nuovo vettore di payoff.


> b <- c(112,106,104)
>Y
                            bond stock risky stock
lucky state        104      108                  112
neutral state    104      102                  106
gloomy state      104      100                    93
> # Posso risolvere Yx=b (con il nuovo b)?
# Stessa procedura:
> qr(Y)$rank
[1] 3
> qr(cbind(Y,b))$rank
[1] 3
> pesi <- ginv(Y) %*% b #    i pesi con l'inversa generalizzat (assegnandoli ora ad una
variabile)
> pesi
[,1]
[1,] 3.846154e-02
[2,] 1.000000e+00
[3,] 1.776357e-15

> # Risultato interessante.


    #Questo significa che se compriamo 0.03846 della prima colonna,
    #e 1 della seconda ottengo il    b= (112,106,104)
  
> cbind(Y,b)
                            bond stock risky stock      b
lucky state        104      108                  112 112
neutral state    104      102                  106 106
gloomy state      104      100                    93 104
> # Quanto ci costa il payoff b?

> sum(pai*pesi) # Sommo i prezzi per le quantità


[1] 103.8462
> #Quindi per 103.85 puoi ottenere un payoff b
>
> # Perchè pagare di più per il payoff b? RISPETTO A?
>
> # paghiamo il costo addizionale per essere protetti
    # da in alcuni stati del mondo (è come un' assicurazione)
>
> # Inoltre b è un portafoglio bilanciato.    dove azioni sono mixate con obbligazioni;
    #b è un mix (bilanciato) di obbligazioni in piccola quantità e di azioni relativamente poco
rischiose.

> #arbitraggio: Situazione in cui puoi fare soldi senza rischio (ci sono due asset uguali a
prezzi diversi).
> # in questo caso è possibile intascarsi la differenza
> # si vedano le note e le slides
> # Una economia:
> Y <- matrix(c(104,104,104,108,102,100,112,106,104),3,3)
>Y
          [,1] [,2] [,3]
[1,]    104    108    112
[2,]    104    102    106
[3,]    104    100    104
> pai <- c(100,100,104) # prezzi
> # Io posso comprare la terza colonna (asset) per 104,
    #ma posso anche replicarla utilizzando le prime due colonne.

> # La replicazione si riduce al sistema:


> # Y[,1:2] %*% x = Y[,3]
> # usiamo il teorema di RC:
> qr(Y[,1:2])$rank # rango matrice composta dalla prime due colonne
[1] 2
> # e della matrice completa
> qr(Y)$rank
[1] 2
> #Conclusioni? Esistono soluzioni.
> solve(Y[,1:2],Y[,3])    # Ma naturalmente la matrice Y[,1:2] non è quadrata, ergo solve non
funziona
Error in solve.default(Y[, 1:2], Y[, 3]) :
    'a' (3 x 2) deve essere quadrata
> library(MASS) # per accedere al comando ginv
# non possiamo calcolare l'inversa di una matrice non quadrata.
# usiamo la ginv per trovare una soluzione (pesi):
> x <- ginv(Y[,1:2]) %*% Y[,3]
>x
                      [,1]
[1,] 0.03846154
[2,] 1.00000000
> Y[,1:2] %*% x # moltiplicando i pesi per i payoff dei due asset troviamo... esattamente i
payoff the secondo asset:
          [,1]
[1,]    112
[2,]    106
[3,]    104
> # la replicazione è chiaramente possibile!

> # Quanto costa replicare III usando le colonne I e e II?


> pai
[1] 100 100 104
> x[1]*pai[1]+x[2]*pai[2] # sommo i pesi trovati*prezzi
> 0.03846154*100+1*100
[1] 103.8462
> # Questo è il prezzo della replicazione, circa 103.85
> # C'è un opportunità di arbitraggio visto che il prezzo di III è 104!
>
> # C'è un'altra interpretazione di arbitraggio. Una situazione in cui hai un payoff nullo con un
prezzo non nullo
#    Considera:
> y <- c(-0.03846154,-1,+1)
> # Il significato è: vendi -0.038 di I, vendi -1 di II e compra 1 unità di III.
>
> #Il payoff di y?
> Y %*% y # moltiplico la matrice che rappresenta i payoffs per questo vettore di operazioni.
                  [,1]
[1,] -1.6e-07
[2,] -1.6e-07
[3,] -1.6e-07
> # Questo è (numericamente parlando) un vettore nullo
> # Quanto costa (netto) il portafoglio y?
> sum(y*pai)
[1] 0.153846
# quindi c'è una serie di operazioni con payoff nullo ma costo non nullo. In questo caso nulla
di che... ma se
> y2 <- c(0.03846154,1,-1) # prendiamo lo stesso portafoglio, coi segni invertiti
> sum(y2*pai)
[1] -0.153846
#    Possiamo avere un prodotto che rende zero, con una serie di operazioni il cui costo è -
0.153846. Occasione di arbiraggio
>
> # ricorda che l'arbitraggio è possibile se il prezzo del replicante è superiore o inferiore al
prezzo di mercato.

> # Risolviamo l'esercizio 14 mock 101


# notate che i vettori degli asset sono vettori colonna... quindi non uso byrow (o uso
byrow=F).
> Y <- matrix(c(118,99,109,96,101,92,84.6, 80, 81.4),3,3)
>Y
          [,1] [,2] [,3]
[1,]    118      96 84.6
[2,]      99    101 80.0
[3,]    109      92 81.4
> pai <- c(100.16,87.17,74.546) #definisco i prezzi
> # Q: Il terzo asset è replicabile?
> qr(Y[,1:2])$rank #calcolo il rango della matrice con gli altri due componenti
[1] 2
> qr(Y[,1:3])$rank #e della matrice completa
[1] 3
> # Il sistema non ha soluzioni. Dunque? Non replicabile, no arbitraggio (!!!)
> # Nota importante:
> # Anche se il sistema non ha soluzioni e, dunque,non c'è arbitraggio, attenti al fatto che
    # (se non controllate e lo utilizzate subito), ginv funziona ugualmente!
> ginv(Y[,1:2]) %*% Y[,3] #ginv genera una inversa e la possiamo moltiplicare per il terzo
elemento
                    [,1]
[1,] 0.3869191
[2,] 0.4145673
> x <- ginv(Y[,1:2]) %*% Y[,3]
> # ma x non replica la colonna III. Ne è solo un'approssimazione.
> Y[,1:2] %*% x
                  [,1]
[1,] 85.45492
[2,] 80.17629
[3,] 80.31438
> Y[,3] # infatti III è diverso!
[1] 84.6 80.0 81.4
>
> #Un altro esercizio: 14 mock 102
> Y <- matrix(c(118,106,103,98,99,114,98.2,92.6,97.1),3,3) # i cui prezzi sono 95.70, 93.50,
85.250
>Y
          [,1] [,2] [,3]
[1,]    118      98 98.2
[2,]    106      99 92.6
[3,]    103    114 97.1
> pai <- c(95.7,93.5,85.250) # ecco i prezzi
> # Domanda:    si può replicare III?
> qr(Y[,1:2])$rank
[1] 2
> qr(Y)$rank
[1] 2
> # conclusione: il teorema di RC, dice: si, c'è una replicazione!
> # ora devo controllare i prezzi:
> x <- ginv(Y[,1:2]) %*% Y[,3]
>x
          [,1]
[1,]    0.5
[2,]    0.4
> # Questo significa che 0.5 * I + 0.4* II ==III, controllate!

> 0.5*pai[1]+0.4*pai[2] # Il costo della replicazione è


[1] 85.25
> pai[3] # esattamente lo stesso costo di III
[1] 85.25
> #conclusion?
> # D, la replicazione è possibile ma non c'è possibilità di arbitraggio
>
  
  
  
#    Alcuni esercizi di chiarimento:
    #    ESERCIZIO A:
    # genero le funzioni
> f <- function(x) x+1
> g<- function(x) -x^2-x-5
# le plotto.
> curve(f,-2,3)
> curve(g,-2,3)
#La parabola non si vede!
#    Ho rispettato il mandato dell’esercizio? “Visualizza la retta e la parabola tra -2 e 3”.
#No, perché la parabola non è visibile. Occorre variare l’asse y in modo da includerla.
> curve(f,-2,3,ylim=c(-10,10))
> curve(g,-2,3,add=T)
# Ancora non è sufficiente perché la parabola non è pienamente visualizzata
# Provo con un intervallo più grande.
> curve(f,-2,3,ylim=c(-20,10))
> curve(g,-2,3,add=T)
# ylim definisce l'intervallo di visualizzazione sull'asse delle y
# è necessario utilizzarlo in questo caso in quanto gli assi creati per la prima funzione non
comprendono la seconda.

——
#Giulia ha chiesto:SET.SEED:
# prova A
set.seed(107)
v <- rnorm(100, mean=5, sd= 2)
sum(v[51:58])
# [1] 34.27003
.

# prova B
set.seed(107)
rnorm(100, mean=5, sd= 2)
v <-rnorm(100, mean=5, sd= 2)
sum(v[51:58])
# [1] 31.90451

#perché non è uguale? Perché set seed inizializza i numeri causali per partire dallo stesso
punto
#Ma in “prova b” hai già creato numero diversi prima di procedere con l’assegnazione alla
variabile v

Lezione 13:> # Quante soluzioni ha il sistema di equazioni non lineari:


> # x^2 +2xy+y^2-x = 0;
> # (x-1)^2+(y+1)^2 = 1?
> Calcolare le soluzioni
> f<- function(x,y) x^2+2*x*y+y^2-x
> g<- function(x,y) (x-1)^2+(y+1)^2-1
> x<-seq(-3,3,len=31)
> y<-seq(-3,3,len=31)
> fz<-outer(x,y,f)
> gz<-outer(x,y,g)
> contour(x,y,fz,levels=0)
> contour(x,y,gz,levels=0,add=T)
> grid()
> # trovare le soluzioni del sistema di cui sopra equivale a trovare i minimi della somma dei
quadrati delle funzioni:
> # metodo della somma dei quadrati
> ssq<-function(x,y) f(x,y)^2 + g(x,y)^2
> ssqb<-function(x) ssq(x[1],x[2])
> a<-optim(c(1,-2),ssqb)$par
> b<-optim(c(0,-0.5),ssqb)$par
> c<-optim(c(1,0),ssqb)$par
> d<-optim(c(2,-0.5),ssqb)$par
> points(a[1],a[2],pch=15,col=2)
> points(b[1],b[2],pch=15,col=3)
> points(c[1],c[2],pch=15,col=4)
> points(d[1],d[2],pch=15,col=5)

> # Simulazioni
> # Utilizzate per risolvere problemi "difficili" generando scenari per ottenere informazione
>
> # Di solito usiamo le simulazioni per 2 motivi:
> # 1) quanto è probabile ottenere un risultato "soddisfacente"?
> # 2) Quale è il risultato medio dei miei esperimenti?
> # Ci restituisce un numero di sintesi, per capire il risultato medio (tipicamente si usa la
media, a volte la deviazione standard)
>
>
> # Le simulazioni sono basate su numeri random
    # Un numero random è il risultato numerico di un esperimento casuale, come tirare un
dado.
> runif(3)
[1] 0.58297886 0.06174449 0.46996278
> runif(3)
[1] 0.06649013 0.18071290 0.76397416
>
> runif(2,min=-3,max=3) # 2 experimenti estraendo dall'intervallo [-3,3]
[1] -1.976554 -1.183906
> runif(2,min=-3,max=3)
[1] -1.2725842    0.6776299
>
> help(runif) # per esplorare eventuali altri parametri aggiuntivi
starting httpd help server ... done

> # density function dname


> x<-seq(-3,3,len=50)
#density function: è un modo di descrivere un esperimento random.
> curve(dunif(x,-3,3),-4,4)
> # plottiamo la densità d della distribuzione normale standard con media zero e sd 1,
sull'intervallo [-4,4]:
> curve(dnorm(x,0,1),-4,4)
> dnorm(x,0,1)
[1] 0.004431848 0.006351346
[3] 0.008966748 0.012470747
[5] 0.017085916 0.023060692
[7] 0.030661593 0.040161080
[9] 0.051820829 0.065870600
[11] 0.082483519 0.101749208
[13] 0.123646888 0.148021104
[15] 0.174563074 0.202800687
[17] 0.232099796 0.261678710
[19] 0.290636609 0.317995184
[21] 0.342751262 0.363936722
[23] 0.380680815 0.392269371
[25] 0.398195275 0.398195275
[27] 0.392269371 0.380680815
[29] 0.363936722 0.342751262
[31] 0.317995184 0.290636609
[33] 0.261678710 0.232099796
[35] 0.202800687 0.174563074
[37] 0.148021104 0.123646888
[39] 0.101749208 0.082483519
[41] 0.065870600 0.051820829
[43] 0.040161080 0.030661593
[45] 0.023060692 0.017085916
[47] 0.012470747 0.008966748
[49] 0.006351346 0.004431848
>
> sum(dnorm(x,0,1)) # sommo i valori di densità calcolati per i vari x
[1] 8.148779
# ATTENZIONE: Perché non somma a 1? La distribuzione normale è una distribuzione
continua --> Sommando le densità è non si ottiene la probabilità di essere in un determinato
intervallo. Per fare questo occorrerebbe fare l'integrale della funzione di distribuzione da tra i
due estremi dell'intervallo.
# Purtroppo R (al contrario di altri programmi - di cui il mio errore) non calcola integrali
direttamente quindi l'operazione che ho tentato era sbagliata concettualmente.

# Possiamo comunque calcolare la probabilità di essere tra due valori con la funzione
pnorm(q). Che calcola (numericamente) l'integrale tra meno infinito e q. Per calcolare la
massa sotto la curva (in questo esempio, distribuzione normale, media zero, sd 1) tra due
estremi a= e b:
> pnorm(3) # integrale della distribuzione normale standard(mean=0,sd=1) tra -inf e 3

[1] 0.9986501
> pnorm(-3) # integrale della distribuzione normale standard(mean=0,sd=1) tra -inf e -3
[1] 0.001349898
> pnorm(3)-pnorm(-3) l'area tra -3 e 3 sarà data dalla differenza dei due integrali (disegnate la
curva per averne un'intuizione)
[1] 0.9973002

>
> # sample può essere usato per interessanti esperimenti random
> # sample fa dei campionamenti!
> # sample(x, size, options)
> # x è l'insieme da cui fai campionamento
> # size è il numero di estrazioni
> # sample(x, size, replace=T/F, prob=NULL)
> # se prob=NULL, di default, allora tutti gli oggetti in x sono campionati con la stessa
probabilità> # sample(x,size,options)
> # sample(x,size,replace=F,prob=NULL)
> sample(c(0,1,5),2)# campiona senza reintroduzione 2 numeri dalla lista 0,1,5
[1] 5 1
> sample(c(0,1,5),2)
[1] 5 1
>
> sample(c(0,1,5),2)
[1] 1 0
>
>
> sample(c(0,1,5),10) # non posso campionare senza reintroduzione più valori di quelli che
ho ne set:
Error in sample.int(length(x), size, replace, prob) :
    cannot take a sample larger than the population when 'replace = FALSE'
> sample(c(0,1,5),10,replace=T) # con reintroduzione
[1] 1 5 5 1 5 0 0 0 5 0
> sample(c(0,1,5),10,rep=T)
[1] 5 0 0 1 5 0 1 0 1 1
>
> # simuliamo un dado
> sample(1:6,1) # campiona un valore intero tra 1 e 6, con prob uniforme per tutti i valori
[1] 1
> sample(1:6,1)
[1] 5
>
# campiona 2 valori interi tra 1 e 6, con reintroduzione e con prob uniforme per tutti i valori
> sample(1:6,2,rep=T) # naturalmente simulare più dadi richiede di introdurre la
reintroduzione (replacement)
[1] 4 5
> sample(1:6,10,rep=T) # uguale ma 10 dadi
[1] 6 5 5 3 2 1 1 6 6 2

> # dado truccato!


> # Si assuma ora che il mio dado,
    # che ho tirato sei volte, sia truccato:
> sample(1:6,10,rep=T,prob=c(1,1,1,1,1,4)) # in questo caso il valore 6 ha 4 volte la
probabilità di essere estratto rispetto agli altri.
[1] 3 6
> 1/sum(1+1+1+1+1+4)
[1] 0.1111111
> 4/sum(1+1+1+1+1+4)
[1] 0.4444444
>
>
>    # COMITATO - il mio primo script per simulare
>    # Formazione di un comitato
>    # venditori, marketing, produzione, HR
>    # si assuma di voler creare un commitato # estraendo dal personale: 4 vend, 3 mar, 5 #
production, 3 HR
> # comitati di 4 persone
> # probabilità di avere almeno 3 skill nel comitato
> personale<- c()
> str(personale)
NULL
> # rep(values,times)
> # rep(values,times) ripete il valore o sequenza di valori values un numero ti volte times
> rep(c(1,0),3)
[1] 1 0 1 0 1 0
> personale<- c(rep("vend",4),rep("mar",3),rep("prod",5),rep("HR",3))
> personale
[1] "vend" "vend" "vend" "vend" "mar"    "mar"
[7] "mar"    "prod" "prod" "prod" "prod" "prod"
[13] "HR"      "HR"      "HR"   
> # creare un comitato di 4 persone, alcune estrazioni
> sample(personale,4)
[1] "mar"    "vend" "prod" "HR"   
> sample(personale,4)
[1] "vend" "vend" "mar"    "vend"
>    # volendo creare un comitato truccato (con probabilità di estrazione deiverse, posso
riutilizzare rep:
> probabil<- c(rep(2,4),rep(1,3),rep(1,5),rep(1,3))
> probabil
[1] 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1
> sample(personale,4,rep=F,prob=probabil) # alcune estrazioni truccate
[1] "vend" "prod" "HR"      "prod"
> sample(personale,4,rep=F,prob=probabil)
[1] "vend" "mar"    "vend" "vend"
>
> sample(personale,4,rep=F,prob=probabil)
[1] "vend" "mar"    "vend" "vend"
>
>

Lezione 14:

>    # COMITATO - il mio primo script per simulare


>      # Formazione di un comitato
>      # venditori, marketing, produzione, HR
>      # si assuma di voler creare un commitato # estraendo dal personale: 4 vend, 3 mar, 5 #
production, 3 HR
>    # comitati di 4 persone
>    # probabilità di avere almeno 3 skill nel comitato

# Dalla scorsa lezione:


> personale<-c()
> personale<- c(rep("vend",4),rep("mar",3),rep("prod",5),rep("HR",3))
> sample(personale,4,replace=F) # creare un comitato di 4 persone, alcune estrazioni
[1] "prod" "HR"      "mar"    "prod"
> sample(personale,4,replace=F)
[1] "prod" "mar"    "vend" "prod"
>
# Ora vogliamo calcolare la probabilità di avere almeno tre skills diversi.

# Ci servono alcuni comandi:


> comitato<-sample(personale,4,replace=F)
> comitato
[1] "prod" "vend" "vend" "mar"
# unique restituisce gli elementi che appaiono, solo una volta (anche se emergono più volte)
> unique(comitato)
[1] "prod" "vend" "mar"
> length(unique(comitato)) # restituisce la lunghezza del vettore degli elementi calcolati solo
una volta
[1] 3
# 3 (sopra) è il numero di skill unici nel gruppo.
# Come generalizzare?
  
    #Ci serve un nuovo comando, for:
> # for(indice in    da:a){COMANDI}
> for(i in 1:3){cat("Elena")} # cat sta semplicemente per "concatenate and print"
ElenaElenaElena
> for(i in 1:10){print(sqrt(i))}
[1] 1
[1] 1.414214
[1] 1.732051
[1] 2
[1] 2.236068
[1] 2.44949
[1] 2.645751
[1] 2.828427
[1] 3
[1] 3.162278
# Scriviamo uno script per il problema precedente (IN FILE SEPARATO)
> comitato<- function(niter=10) {
+ res<- rep(0,niter) # vettore per i risultati (inizializziamo a zero)
+ personale<- c(rep("vend",4),rep("mar",3),rep("prod",5),rep("HR",3))
+ for(i in 1:niter) {
+ diversita<-length(unique(sample(personale,4,replace=F)))
+ if (diversita>=3) {res[i]<-1}
+ } # graffa che chiude il for
+ sum(res)/niter
+}
# 10 iterazioni (default
> comitato()
[1] 0.9
> comitato(100) #    100 iterazioni
[1] 0.76
>
> comitato(1000) # 1000 iterazioni
[1] 0.743
> comitato(10000) # 10000 iterazioni
[1] 0.7463
> comitato(100000) # 100000 iterazioni
[1] 0.75251
>
>
> # ESERCIZIO 2:
>    #La qualità di un nuovo bene può essere valutata con 2 misure numeriche.
>      #Assumi che siano numeri random uniformi. Stima quanto probabile sia che il massimo
delle misure ecceda 0.5.
> # a) About 0.22; b) About 0.75; c) About 0.9; d) About 0.39.
>
>
#Scriviamo uno script in una finestra separata:
> N<- 1000
> res <- rep(0,N) # var x i risultati
> for (i in 1:N) {
+ x<-runif(2)
+ if (max(x)>0.5) {res[i]<-1}
+}
*** Il codice qui sopra è stato fatto girare cliccando    command + enter sul mio mac ***
> sum(res)/N # ora posso stimare la probabilità di ottenere res=1
[1] 0.776
> res
      [1] 1 0 1 1 0 1 0 1 1 1 1 0 1 1 0 0 1 1 1 1
    [21] 1 1 0 1 1 1 1 1 1 1..... (ho omesso il resto per avere un file compatto)

> #La qualità di un nuovo bene può essere valutata con 2 misure numeriche.
> #Assumi che siano numeri random uniformi. Stima quanto probabile sia che il massimo
delle misure ecceda 0.5.
> # a) About 0.22; b) About 0.75; c) About 0.9; d) About 0.39.
>
>
> # Un modo alternativo di risolvere:
# Definisco una funzione con un singolo esperimento:
> experiment<-function() max(runif(2))>0.5
> experiment()
[1] TRUE
# Poi uso il comando “replicate” per replicare molti esperimenti.
# struttura di replicate:    replicate(number, experiment())
> res<-replicate(1000,experiment())
> res
      [1]    TRUE FALSE FALSE    TRUE    TRUE    TRUE
      [7]    TRUE    TRUE    TRUE    TRUE    TRUE FALSE
    [13]    TRUE    TRUE    .... (omesso il resto per compattezza del file di output
> # replicate(number,funzione)
> sum(res)/1000 # ricordiamoci che a TRUE è associato il valore 1 e a FALSE il valore 0.
[1] 0.779
> sum(res==FALSE) # per contare i falsi invece che i veri
[1] 221
>
# Cosa abbiamo imparato:
# Posso utilizzare loop espliciti per programmare degli esperimenti, ma posso anche #
definire un singolo esperimento e replicarlo tante volte.

# ---------
>
>Tornando al esercizio del comitato:
Ho lavoratori di diversi tipi e voglio formare comitati di 4 persone, quale probabilità che
almeno tree skills siano rappresentati.

> personale <- c(rep("sales",4),rep("marketing",3),rep("production",5),rep("HR",2))


> length(unique(sample(personale,4)))
[1] 3
# ora sono pronto per scrivere il mio esperimento singolo:

> experiment <-function() {


+ personale <- c(rep("sales",4),rep("marketing",3),rep("production",5),rep("HR",2))
+ comitato<-sample(personale,4)
+ length(unique(comitato))}
# posso fare un singolo esperimento
> experiment()
[1] 3
> experiment()
[1] 3
# o utilizzare replicate per fare più esperimenti
> replicate(10,experiment())
[1] 3 3 3 3 3 3 2 3 3 2
# molti più esperimenti e calcolo probabilità
> res<-replicate(1000,experiment())
> sum(res>=3)/1000
[1] 0.743
>
# E se vi chiedessi il numero medio di skills di un comitato di 4?
# res is storing the number of skills
> mean(res)
[1] 2.852
> sd(res)
[1] 0.6003803
e se volessi caratterizzare l’intera distribuzione?

> hist(res)
>

Lezione 15:
> #Si paga un prezzo 100 per ottenere un valore casuale tra (1000,100,1) con    probabilità
1/6,2/6,3/6. quale è il guadagno medio?
> revenues<-sample(c(1000,100,1),1000,rep=T,prob=c(1/6,2/6,3/6))
> revenues[1:10]
[1]      1 100      1 100      1 100 100 100      1 100
> mean(revenues)-100 # guadagno è entrate meno costi:
[1] 115.785

# NIDIFICARE PROBLEMI E SINGOLI ESPERIMENTI PARAMETRIZZATI

> # Problema dei Compleanni


> # Quanto è probabile ottenere ALMENO UN compleanno duplicato in un gruppo di N
persone? Dovrebbe essere basso….qualcosa dell’ordine di: N/365

# Naturalmente questo problema classico si risolve con le probabilità… ma noi useremo le


simulazioni!

# Definirò un singolo esperimento:

> days<-1:365
> birthdays<-sample(days,10,rep=T) # compleanni di un gruppo di 10 persone
> birthdays
[1] 122 365 278 250 302    72    91 104 136 241
> # duplicated
> # Dall’help: duplicated determines which elements of a vector or data frame are duplicates
of elements with smaller subscripts, and returns a logical vector indicating which elements
(rows) are duplicates.
> duplicated(birthdays)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[8] FALSE FALSE FALSE
> sum(duplicated(birthdays))
[1] 0
> # definire innanzitutto un singolo esperimento
> experiment<-function(n) {# n numero di persone nel gruppo
+ days<-1:365
+ birthdays<-sample(days,n,rep=T)
+ sum(duplicated(birthdays))
+}
> experiment(10)
[1] 0
> experiment(56) # n=56 persone
[1] 4
#    Possiamo usare “replicate” per replicare questo esperimento.
> res<-replicate(1000,experiment(56))
> res
      [1]    4    5    6    3    3    3    9    2    4    5    8    6    3
    [14]    1    4    7    4    3    6    2    1    8    6    2    5    4
    [27]    3    2    3    2    1    4    4    4    4    4    4    7    6
    [40]    5    7    4    2    3    ... (output tagliato per pulire il file
#    99% delle volte c’è un compleanno comune in un gruppo di 56:
> sum(res>=1)/1000
[1] 0.99
> # 56 persone, la probabilità di 0.99
> # 99%!
>
> #    E se tu volessi sapere come cambia la probabilità per diversi n (diciamo da 1 a 60)?
> # 1. definire una funzione per calcolare la probabilità di un compeanno in comune per dato
n.
> comple<-function(n){
+ res<-replicate(1000,experiment(n))
+ sum(res>=1)/1000
+}
> comple(56)
[1] 0.994
> comple(10)
[1] 0.142
>
> # 2. chiedere a R di replicare questa operazione comple(n) per n da 1 a 60
> # sapply: simply apply
> # sapply(x,function): applica la funzione a tutti gli elementi di x e ritorna un vettore con i
risultati.
#    Noi vogliamo applicare "comple" al vettore con le dimensioni del gruppo n per cui
vogliamo calcolare la probabilità di avere compleanni comuni
> x<-1:60
> y<-sapply(x,comple)
> plot(x,y,xlab="x-Dimensione del gruppo",ylab="Prob. di un comple comune")
>
>
>
> # PROBLEMA DI MONTY HALL
> # Il problema di    Monty Hall (vedere anche slides Lezione 13-14-15): l’idea è di utilizzare le
simulazioni per comparare due strategie:
> # - tieni
> # - cambia
>
> #    Assumeremo (senza perdere di generalità), che la macchina sia sempre    nella prima
porta (ma che noi non lo si sappia quando prendiamo la decisione).
>
> # KEEP: TIENI LA PORTA SCELTA
> # programmare un singolo esperimento
> if(sample(1:3,1)==1) 1 else 0 # se estriamo 1 vinciamo altrimenti perdiamo
[1] 0
# Ricordiamoci il comando replicate:    replicate(1000 volte, il precedente esperimento):
> res<-replicate(1000,if(sample(1:3,1)==1) 1 else 0)
> sum(res)/1000
[1] 0.352
#    Quindi la probabilità di successo è circa    352/1000 ~ 1/3
>
> # Vediamo ora la Probabilità di vincere con la strategia Switch (cambia la porta):
> expswitch<-function() {
+ pick<-sample(1:3,1)
+ # il presentatore ora ci mostra una porta con la capra
+ if(pick==1) show<-sample(2:3,1)
+ if(pick==2) show<-3
+ if(pick==3) show<-2
+ # noi prendiamo sistematicamente la porta che rimane
+ taken<-(1:3)[c(-pick,-show)]
+ if(taken==1) 1 else 0
+}
# testiamo che funzioni:
> expswitch()
[1] 1
> expswitch()
[1] 0
>
# Ora faccio 1000 iterazioni: dell’esperimento:
> res<-replicate(1000,expswitch())
> sum(res)/1000
[1] 0.648
# La probabilità di vincere è    665/1000 ~ 2/3

# Conviene sempre cambiare porta (dato che il presentatore ci ha mostrato una porta
contendente una "capra")
>
>
>
> # SIMULAZIONI PER RISOLVERE PROBLEMI DI MATEMATICA
> #Consideriamo questo quadro di Mirò:
> curve(x^2,-2,2,ylim=c(0,2))
> curve(log(x+4),add=T)
# voglio calcolare l’area della “lingua” tra le due funzioni
> # METODO 1: integrali
# Vediamo come usare le simulazioni per affrontare questo problema

# L’area di cui calcolare il valore sta tra le due curve e si può calcolare utilizzando l’integrale
di una funzione.

# Che funzione? Quella che descrive il valore della differenza tra le 2 (dato che la prima sta
sempre sotto la seconda):
> diff<- function(x) log(x+4)-x^2    # scrivo una funzione come differenza delle 2
# Innanzitutto
mi computo le due intersezioni:
> uniroot(diff,c(-1.5,0.5))
$root
[1] -1.041483

(RESTO DELL'OUTPUT OMESSO PER COMPATTEZZA)

> uniroot(diff,c(1,1.5))
$root
[1] 1.290722

(RESTO DELL'OUTPUT OMESSO PER COMPATTEZZA)

# Gli zeri sono relativamente    -1.041483,1.290722

# L’area sotto la curva è l’integrale dal primo al secondo valore della funzione “diff”:

> integrate(diff,-1.041483,1.290722)
2.179504 with absolute error < 2.4e-14
>
> # METODO 2: con    le simulazioni
# Proviamo ora a computare questo numero con una simulazione:

> inside <- function() {


+ x<-runif(1,-2,2)
+ y<-runif(1,0,2)
+ if(y>x^2 & y<log(x+4)) {points(x,y,col=2); 1} else 0
+}
Faccio alcuni esperimenti:
> replicate(20,inside())
[1] 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
> res<-replicate(10000,inside()) # e poi molti di più
> sum(res)/10000
[1] 0.2677
> # da -2 a 2 --> lunghezza 4
> # da 0 a 2 --> altezza 2
> # 2*4 =8
Il 26.77% dei punti.
La nostra area di lavoro è un rettangolo con base da -2 a 2 (lunghezza 4), e altezza da 0 a 2
(altezza 2).
L’area è 8.
Quindi l’area rossa deve essere il 26.77% di 8:
> (sum(res)/10000)*8
[1] 2.1416
# che possiamo confrontare con l’output analitico di    2.179:
> 2.1416-2.179504
[1] -0.037904
# Ottima precisione!
>
>
>
> #RISOLVIAMO IL    ES. 16 mock 103
> #Run a simulation to estimate the probability that a standard random uniform is bigger than
another uniform random number in [0:3;1:1].
> #a) About 0.405; b) About 0.356; c) About 0.306; d) About 0.257.
> #[0.3;1.1].
>
> experiment<- function(){
+ if(runif(1)>runif(1,0.3,1.1)) 1 else 0
+}
> res<-replicate(10000,experiment())
> sum(res)/10000
[1] 0.3041
> # naturalmetne c
>
>
> # come bonus non esaminabile abbiamo visto il Conway's game of life (si veda sezione
apposita di moodle per curiosità).

Potrebbero piacerti anche