class: center, middle, inverse, title-slide # Le funzioni ### Stefano Bussolon ### 3 gennaio 2019 --- ## Funzioni R mette a disposizione numerose funzioni. Inoltre, è possibile scaricare, installare e richiamare delle librerie esterne, che mettono a disposizione altri insiemi di funzioni. --- Per iniziare a *giocare* con R, introduciamo le funzioni length, min, max, sum, mean. * `length(v)` serve per conoscere la lunghezza (il numero di elementi) del vettore `v`. * `min(v)` ritorna il valore più basso di un vettore `v`, `max()` il più alto. * `sum(v)` somma i valori del vettore. `prod(v)` calcola il prodotto dei valori. * `mean(v)` calcola la media, `sd(v)` la deviazione standard --- ```r variabile1 <- c(2,3,6,4,8,4,1) length(variabile1) ``` ``` ## [1] 7 ``` ```r min(variabile1) ``` ``` ## [1] 1 ``` ```r max(variabile1) ``` ``` ## [1] 8 ``` --- ```r # somma tutti i valori sum(variabile1) ``` ``` ## [1] 28 ``` ```r # moltiplica tutti i valori prod(variabile1) ``` ``` ## [1] 4608 ``` ```r # mean calcola la media mean(variabile1) ``` ``` ## [1] 4 ``` ```r # sd calcola la deviazione standard sd(variabile1) ``` ``` ## [1] 2.380476 ``` --- ## Generare delle sequenze La funzione [seq](https://stat.ethz.ch/R-manual/R-devel/library/base/html/seq.html) genera delle sequenze. La sintassi più semplice, `seq(from,to)` crea una sequenza dal primo valore all'ultimo con *step* 1. Il comando `c(from:to)` è del tutto equivalente, ed utilizza il cosiddetto [Colon Operator](https://stat.ethz.ch/R-manual/R-devel/library/base/html/Colon.html). `seq(0,1000, length=11)` genera una sequenza di 11 numeri da 0 a 1000: 0, 100, 200 ... 1000. --- ```r (vettore1 <- seq(1,10)) ``` ``` ## [1] 1 2 3 4 5 6 7 8 9 10 ``` ```r # seq (n) è uguale a seq(1,n) seq(10) ``` ``` ## [1] 1 2 3 4 5 6 7 8 9 10 ``` ```r # c(a:b) == seq(a,b) c(1:10) ``` ``` ## [1] 1 2 3 4 5 6 7 8 9 10 ``` ```r # genera una sequenza di lunghezza length seq(0,1000, length=11) ``` ``` ## [1] 0 100 200 300 400 500 600 700 800 900 1000 ``` --- ## Ripetizione La funzione `rep(v,n)` ripete un vettore `n` volte. ```r # ripete 2 10 volte rep(2,times=10) ``` ``` ## [1] 2 2 2 2 2 2 2 2 2 2 ``` ```r rep(c(2,4),times=10) ``` ``` ## [1] 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 ``` ```r # crea un vettore di lunghezza 10 rep(c(2,4),length=10) ``` ``` ## [1] 2 4 2 4 2 4 2 4 2 4 ``` --- ```r # concateno due sequenze sequenze1 <- c(seq(0,1000, length=11),seq(1000,0, length=11)) sequenze1 ``` ``` ## [1] 0 100 200 300 400 500 600 700 800 900 1000 1000 900 800 ## [15] 700 600 500 400 300 200 100 0 ``` * `rep(c(2,4,3),times=10)` ripete 10 volte i valori 2, 4 e 3, creando un vettore di 30 elementi. * `rep(c(2,4),length=10)` crea un vettore di lunghezza 10. * `rep_len(x, n)` equivale a `rep(x,length=n)` --- ## sample La funzione `sample(v,n)` estrae `n` valori, in ordine casuale, dal vettore `v`. `sample` *estrae* casualmente i valori dal vettore - la metafora è quella di un'urna da cui vengono estratti i *numeri*. Se `replace=FALSE` un valore estratto non viene re-immesso nell'urna. Con `replace=TRUE` viene re-immesso, e può essere estratto di nuovo. `sample(v)` può essere usata per *mescolare* l'ordine del vettore `v`. --- ```r # mescola il vettore (mischiato <- sample (vettore1)) ``` ``` ## [1] 8 5 3 1 6 10 7 2 9 4 ``` ```r # sample (v,n) fa il sample e restituisce i primi n numeri sample(vettore1, 4) ``` ``` ## [1] 1 2 8 5 ``` ```r # se lo rifaccio, avrò numeri differenti sample(vettore1, 4) ``` ``` ## [1] 9 4 1 5 ``` ```r # con replace = TRUE i valori estratti vengono rimessi nell'urna sample(1:4,10,replace = TRUE) ``` ``` ## [1] 1 4 3 3 3 1 4 4 3 3 ``` --- ## Ordinare un vettore ```r # ordina un vettore # decreasing = TRUE ordine decrescente sort(mischiato) ``` ``` ## [1] 1 2 3 4 5 6 7 8 9 10 ``` ```r order(mischiato) ``` ``` ## [1] 4 8 3 10 2 5 7 1 9 6 ``` ```r mischiato[order(mischiato)] ``` ``` ## [1] 1 2 3 4 5 6 7 8 9 10 ``` --- `sort(mischiato)` ordina il vettore, dal valore minore al maggiore. `sort(mischiato,decreasing=TRUE)` per l'ordine inverso. `order(mischiato)` ritorna la permutazione necessaria per ordinare mischiato --- ## Rev `rev(v)` *rovescia* l'ordine degli elementi del vettore. ```r # rev(x) gira x rev(vettore1) ``` ``` ## [1] 10 9 8 7 6 5 4 3 2 1 ``` ```r rev(mischiato) ``` ``` ## [1] 4 9 2 7 10 6 1 3 5 8 ``` --- ## cbind, rbind `cbind` e `rbind` creano delle matrici legando vettori o matrici in colonne (cbind) o in righe (rbind). ```r # rbind prende gli argomenti e li mette una riga dopo l'altra rbind(c(1,2),c(3,4),c(5,6)) ``` ``` ## [,1] [,2] ## [1,] 1 2 ## [2,] 3 4 ## [3,] 5 6 ``` ```r # incolonna gli argomenti cbind(c(1,2),c(3,4),c(5,6)) ``` ``` ## [,1] [,2] [,3] ## [1,] 1 3 5 ## [2,] 2 4 6 ``` --- ### all, any `all(v)` e `any(v)` possono essere interpretate come delle estensioni degli operatori logici `&` e `|` (and e or). `all(v)` restituisce `TRUE` solo se *tutti* i valori del vettore logico *v* sono veri. `any(v)` restituisce `TRUE` se *almeno uno* dei valori del vettore logico *v* sono veri. --- ```r # l'operatore logico & equivale alla funzione all (con 2 argomenti) TRUE & FALSE ``` ``` ## [1] FALSE ``` ```r all(TRUE,FALSE) ``` ``` ## [1] FALSE ``` ```r # l'operatore logico | equivale alla funzione any (con 2 argomenti) TRUE | FALSE ``` ``` ## [1] TRUE ``` ```r any(TRUE,FALSE) ``` ``` ## [1] TRUE ``` --- ```r (logico1 <- mischiato>5) ``` ``` ## [1] TRUE FALSE FALSE FALSE TRUE TRUE TRUE FALSE TRUE FALSE ``` ```r all(logico1) ``` ``` ## [1] FALSE ``` ```r any(logico1) ``` ``` ## [1] TRUE ``` --- ## Operazioni su insiemi Operazioni di intersezione, unione, differenza, uguaglianza di insiemi. In queste operazioni vengono considerati i valori unici presenti nei vettori, e non viene considerato l'ordine degli elementi. --- ```r (vettore2 <- c(seq(6,15),rep(8,3))) ``` ``` ## [1] 6 7 8 9 10 11 12 13 14 15 8 8 8 ``` ```r # intersect (v1, v2) restituisce i valori in comune intersect(mischiato, vettore2) ``` ``` ## [1] 8 6 10 7 9 ``` ```r # tutti i valori che appaiono almeno una volta # nell'unione dei due vettori union(mischiato, vettore2) ``` ``` ## [1] 8 5 3 1 6 10 7 2 9 4 11 12 13 14 15 ``` ```r # setdiff(v1,v2): i valori di v1 NON presenti in v2 setdiff(mischiato, vettore2) ``` ``` ## [1] 5 3 1 2 4 ``` --- ```r # restituisce TRUE se i due vettori hanno gli stessi elementi setequal(mischiato, vettore2) ``` ``` ## [1] FALSE ``` ```r setequal(mischiato, vettore1) ``` ``` ## [1] TRUE ``` ```r # perché? setequal(c(2,4,5,6), c(4,2,5,6,5,2)) ``` ``` ## [1] TRUE ``` --- # Aritmetica delle matrici R permette sofisticate operazioni di aritmetica dei vettori e delle matrici. Riportiamo gli esempi più semplici. --- ```r vettore1 <- c(1:9) vettore1*2 ``` ``` ## [1] 2 4 6 8 10 12 14 16 18 ``` Apparentemente, `vettore1*2` moltiplica vettore1 per lo scalare 2. In realtà, `2` non è uno scalare, ma un vettore di lunghezza 1, che viene *riciclato* per la lunghezza di `vettore1`. La logica diviene evidente se moltiplichiamo `vettore1` per un vettore di lunghezza 3. --- ```r vettore2 <- c(1,2,3) vettore1*vettore2 ``` ``` ## [1] 1 4 9 4 10 18 7 16 27 ``` Come si può vedere, `vettore2` è stato riusato 3 volte per moltiplicare `vettore1`. Questa operazione viene definita *element-wise multiplication*, e si distingue dalla moltiplicazione di matrici, che si ottiene con la sintassi `A %*% B`, ma che qui non verrà trattata. --- Vediamo alcuni esempi con le matrici ```r matrice1 <- matrix (c(5,7,1,6,9,5,2,1,9,5,7,5), nrow =3, ncol=4) matrice1 ``` ``` ## [,1] [,2] [,3] [,4] ## [1,] 5 6 2 5 ## [2,] 7 9 1 7 ## [3,] 1 5 9 5 ``` ```r matrice1 * 3 ``` ``` ## [,1] [,2] [,3] [,4] ## [1,] 15 18 6 15 ## [2,] 21 27 3 21 ## [3,] 3 15 27 15 ``` --- ```r # rep (10,12) ripete il numero 10 per 12 volte matrice2 <- matrix (rep(10,12),nrow=3, ncol=4) matrice2 ``` ``` ## [,1] [,2] [,3] [,4] ## [1,] 10 10 10 10 ## [2,] 10 10 10 10 ## [3,] 10 10 10 10 ``` ```r # sommo ogni elemento di matrice1 al # corrispondente di matrice2 matrice1+matrice2 ``` ``` ## [,1] [,2] [,3] [,4] ## [1,] 15 16 12 15 ## [2,] 17 19 11 17 ## [3,] 11 15 19 15 ``` --- ```r # sottraggo, elmento per elemento matrice1-matrice2 ``` ``` ## [,1] [,2] [,3] [,4] ## [1,] -5 -4 -8 -5 ## [2,] -3 -1 -9 -3 ## [3,] -9 -5 -1 -5 ``` ```r # divido matrice1/matrice2 ``` ``` ## [,1] [,2] [,3] [,4] ## [1,] 0.5 0.6 0.2 0.5 ## [2,] 0.7 0.9 0.1 0.7 ## [3,] 0.1 0.5 0.9 0.5 ``` --- ```r matrice3 <- matrix( c(2,3,4,3,2,6,7,8,5,9,5,6), nrow=4,ncol=3, byrow=TRUE) matrice3 ``` ``` ## [,1] [,2] [,3] ## [1,] 2 3 4 ## [2,] 3 2 6 ## [3,] 7 8 5 ## [4,] 9 5 6 ``` ```r # traspongo matrice2 e la sommo a matrice3 t(matrice2)+matrice3 ``` ``` ## [,1] [,2] [,3] ## [1,] 12 13 14 ## [2,] 13 12 16 ## [3,] 17 18 15 ## [4,] 19 15 16 ``` --- # Programmazione funzionale --- ## le funzioni *apply Data una matrice, la funzione `apply(matrice,margine,funzione)` applica la funzione ad ogni cella delle righe o delle colonne della matrice. --- ```r matrice1 <- matrix(sample(1:10,20,replace = TRUE),nrow = 5, ncol = 4) matrice1 ``` ``` ## [,1] [,2] [,3] [,4] ## [1,] 3 10 3 3 ## [2,] 1 1 8 10 ## [3,] 4 9 2 5 ## [4,] 5 1 3 10 ## [5,] 8 10 4 7 ``` ```r # calcola la somma dei valori di ogni riga apply(matrice1, 1, sum) ``` ``` ## [1] 19 20 20 19 29 ``` ```r # calcola la media di ogni colonna apply(matrice1, 2, mean) ``` ``` ## [1] 4.2 6.2 4.0 7.0 ``` --- `sapply(lista,funzione)` applica la funzione agli elementi della lista ```r lista1 <- list(a = 1:10, b = 11:20) lista1 ``` ``` ## $a ## [1] 1 2 3 4 5 6 7 8 9 10 ## ## $b ## [1] 11 12 13 14 15 16 17 18 19 20 ``` ```r sapply(lista1, mean) ``` ``` ## a b ## 5.5 15.5 ``` --- ## Riferimenti * [Vocab · Advanced R.](http://adv-r.had.co.nz/Vocabulary.html) * [adv-r-book-solutions/functions.r at master · peterhurford/adv-r-book-solutions](https://github.com/peterhurford/adv-r-book-solutions/blob/master/03_vocab/functions.r) * [R useful functions](http://www.sr.bham.ac.uk/~ajrs/R/r-function_list.html) * [Useful R base functions - Teaching - RStudio Community](https://community.rstudio.com/t/useful-r-base-functions/4542) * [r - Grouping functions (tapply, by, aggregate) and the *apply family - Stack Overflow](https://stackoverflow.com/questions/3505701/grouping-functions-tapply-by-aggregate-and-the-apply-family) * [Using aggregate and apply in R - Dave Tang's blog](https://davetang.org/muse/2013/05/22/using-aggregate-and-apply-in-r/) * [A brief introduction to “apply” in R | What You're Doing Is Rather Desperate](https://nsaunders.wordpress.com/2010/08/20/a-brief-introduction-to-apply-in-r/) * [R Apply Family](http://people.stern.nyu.edu/ylin/r_apply_family.html) * [How to Aggregate Data in R | R-bloggers](https://www.r-bloggers.com/how-to-aggregate-data-in-r/) * [r - How to sum a variable by group? - Stack Overflow](https://stackoverflow.com/questions/1660124/how-to-sum-a-variable-by-group)