INTRODUCTION TO R

Presentazioni in slideshare:

INTRODUZIONE A R E VETTORI

Vedi presentazione slideshare

Espressioni:

9 + 7
## [1] 16

Assegnamenti:

x <- 6.7

Show variable:

x
## [1] 6.7

Funzioni in R:

x <- nomeFunzione(argomento1, argomento2, argomento3, ...)

Workspace

ls()
## [1] "x"

save.image

writes an external representation of R objects to the specified file. The objects can be read back from the file at a later date by using the function load or data. save.image() is just a short-cut for ‘save my current workspace’, i.e., save(list = ls(all = TRUE), file = “.RData”). It is also what happens with q(“yes”).

save.image("INTRO.RData")

working directory

cwd <- getwd()
cwd
## [1] "/Users/davide/Documents/Devel/R_INTRO"
dir()
## [1] "data.csv"      "INTRO.RData"   "R_Intro.html"  "R_Intro.md"   
## [5] "R_Intro.Rmd"   "R_INTRO.Rproj"
setwd(cwd)

TIPOLOGIE DI DATI IN R

Character
pippo <- "THIS IS A STRING DATA"
class(pippo)
## [1] "character"
Numeric

Numeri reali

n <- 10.01
class(n)
## [1] "numeric"
typeof(n)
## [1] "double"

double = double-precision floating number

Integer

Numeri Interi

i <- -10
class(i)
## [1] "numeric"
typeof(i)
## [1] "double"

In R tutti i numeri sono salvati come double se proprio volete un integer:

y <- as.integer(3)
class(y)
## [1] "integer"
typeof(y)
## [1] "integer"
Logical

Puo avere valori TRUE o FALSE

x <- TRUE
class(x)
## [1] "logical"
typeof(x)
## [1] "logical"
COMPLEX

Numeri complessi

comp <- 7 + 3i
class(comp)
## [1] "complex"
typeof(comp)
## [1] "complex"
RAW BYTES

Sequenze di bytes:

xx <- raw(2)
class(xx)
## [1] "raw"
typeof(xx)
## [1] "raw"
xx
## [1] 00 00

TRANSFORMARE I DATI DA UN TIPO AD UN ALTRO

Per avere informazioni sulla classe a cui appartiene un elemento:
class(n)
## [1] "numeric"
Determinare il Tipo (interno) di dato in R
typeof(n)
## [1] "double"
Verificare se un oggetto appartiene ad una classe od ad un typeof
is.integer(n)
## [1] FALSE
is.character(n)
## [1] FALSE
is.numeric(n)
## [1] TRUE
Convertire un oggetto da una classe ad un altra
n
## [1] 10.01
n1 <- as.integer(n)
n2 <- as.character(n)
Funzioni generiche: “as”“ e "is”
as(n, "integer")
## [1] 10
is(n, "numeric")
## [1] TRUE

FLOAT PRECISION IN R

The only numbers that can be represented exactly in R’s numeric type are integers and fractions whose denominator is a power of 2. Other numbers have to be rounded to (typically) 53 binary digits accuracy. As a result, two floating point numbers will not reliably be equal unless they have been computed by the same algorithm, and not always even then. For example

a <- sqrt(2)
a
## [1] 1.414
a * a
## [1] 2
a * a == 2
## [1] FALSE
a * a - 2
## [1] 4.441e-16
all.equal(a * a, 2)
## [1] TRUE

The function all.equal() compares two objects using a numeric tolerance of .Machine$double.eps ^ 0.5.

Oppure:

x <- seq(1, 20, 0.07)

CFR my Epic Fail: http://permalink.gmane.org/gmane.comp.lang.r.devel/32689

msd <- seq(0.05, 0.3, 0.01)
msd[13]
## [1] 0.17
msd[13] == 0.17
## [1] FALSE
msd[13] - 0.17
## [1] -2.776e-17
all.equal(msd[13], 0.17)
## [1] TRUE

VETTORI

Il Vettore e' la struttura dati piu semplice presente in R.

x <- 4
x
## [1] 4

Anche un oggetto con un singolo elemento (uno scalare) e' un vettore:

is.vector(x)
## [1] TRUE

Con notazione generica:

is(x, "vector")
## [1] TRUE

L'oggetto x e' un vettore che appartiene alla classe numeric con typo di dato double

is.vector(x)
## [1] TRUE
class(x)
## [1] "numeric"
typeof(x)
## [1] "double"

OPERAZIONI SUI VETTORI

concatenate()
y <- c(1, 4, 6, 7, 9)
y
## [1] 1 4 6 7 9

La funzione c() concatena gli elementi passati come argomenti separati da virgola.

Operatore colon (from:to)

Genera una sequenza di valori da a a b per info:

?colon
z <- 1:100
z
##   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17
##  [18]  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34
##  [35]  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51
##  [52]  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68
##  [69]  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85
##  [86]  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100
Contare gli elementi in un vettore
length(z)
## [1] 100
Accedere agli elementi di un vettore

Usiamo un indice tra parentesi quadre

x <- seq(1, 20, 0.5)
x
##  [1]  1.0  1.5  2.0  2.5  3.0  3.5  4.0  4.5  5.0  5.5  6.0  6.5  7.0  7.5
## [15]  8.0  8.5  9.0  9.5 10.0 10.5 11.0 11.5 12.0 12.5 13.0 13.5 14.0 14.5
## [29] 15.0 15.5 16.0 16.5 17.0 17.5 18.0 18.5 19.0 19.5 20.0

Gli indici partono da 1

x[1]
## [1] 1
x[10]
## [1] 5.5
x[20]
## [1] 10.5

Posso anche usare gli operatori visti in precedenza (concatenate e range) per recuperare un gruppo di valori:

x[1:5]
## [1] 1.0 1.5 2.0 2.5 3.0
x[c(1, 10, 20)]
## [1]  1.0  5.5 10.5

Posso utilizzare il segno - per ottenere un vettore che NON contiene gli elementi nella lista:

x <- 1:5
x
## [1] 1 2 3 4 5

x senza il primo elemento:

x[-1]
## [1] 2 3 4 5

x senza gli elementi 1 3 e 5:

x[-c(1, 3, 5)]
## [1] 2 4

COSTRUIRE VETTORI

concatenate
x <- c(1, 2, 4, 6)
x
## [1] 1 2 4 6
colon
x <- 1:100
x
##   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17
##  [18]  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34
##  [35]  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51
##  [52]  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68
##  [69]  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85
##  [86]  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100
seq(from,to,by)
x <- seq(1, 10, 0.1)
x
##  [1]  1.0  1.1  1.2  1.3  1.4  1.5  1.6  1.7  1.8  1.9  2.0  2.1  2.2  2.3
## [15]  2.4  2.5  2.6  2.7  2.8  2.9  3.0  3.1  3.2  3.3  3.4  3.5  3.6  3.7
## [29]  3.8  3.9  4.0  4.1  4.2  4.3  4.4  4.5  4.6  4.7  4.8  4.9  5.0  5.1
## [43]  5.2  5.3  5.4  5.5  5.6  5.7  5.8  5.9  6.0  6.1  6.2  6.3  6.4  6.5
## [57]  6.6  6.7  6.8  6.9  7.0  7.1  7.2  7.3  7.4  7.5  7.6  7.7  7.8  7.9
## [71]  8.0  8.1  8.2  8.3  8.4  8.5  8.6  8.7  8.8  8.9  9.0  9.1  9.2  9.3
## [85]  9.4  9.5  9.6  9.7  9.8  9.9 10.0
rep(x, times)
x <- rep(TRUE, 10)
x
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Esempi

Possiamo combinare due metodi assieme:

x <- c(rep(TRUE, 5), rep(FALSE, 5))
a <- 1:10
b <- seq(1, 5, 0.1)
c <- rep(1, 10)
y <- c(a, b, c)
y
##  [1]  1.0  2.0  3.0  4.0  5.0  6.0  7.0  8.0  9.0 10.0  1.0  1.1  1.2  1.3
## [15]  1.4  1.5  1.6  1.7  1.8  1.9  2.0  2.1  2.2  2.3  2.4  2.5  2.6  2.7
## [29]  2.8  2.9  3.0  3.1  3.2  3.3  3.4  3.5  3.6  3.7  3.8  3.9  4.0  4.1
## [43]  4.2  4.3  4.4  4.5  4.6  4.7  4.8  4.9  5.0  1.0  1.0  1.0  1.0  1.0
## [57]  1.0  1.0  1.0  1.0  1.0
SCAN

Demo

I VETTORI IN R POSSONO CONTENERE SOLO UN TIPO DI DATO

!ATTENZIONE! In molti casi la conversione e' automatica:

x <- as.integer(1:5)
class(x)
## [1] "integer"
x[3] <- 2.7
class(x)
## [1] "numeric"
x[3] <- "TRE"
class(x)
## [1] "character"

CERCARE ELEMENTI IN UN VETTORE

Possiamo usare anche condizioni logiche:

x <- -4:9
x
##  [1] -4 -3 -2 -1  0  1  2  3  4  5  6  7  8  9
x < 2
##  [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
## [12] FALSE FALSE FALSE

la condizione logica x < 2 restiuisce TRUE o FALSE a seconda che l'elemento i-esimo nel vettore soddisfi la condizione x < 2.

La funzione which() restiuisce l'indice degli elementi che soddisfano la condizione x < 2.

xindex <- which(x < 2)
xindex
## [1] 1 2 3 4 5 6

Abbiamo visto come utlizzare un vettore di indici per estrarre gli elementi da un vettore:

x[xindex]
## [1] -4 -3 -2 -1  0  1

Esiste un metodo piu' rapido (una scorciatoia)

x[x < 2]
## [1] -4 -3 -2 -1  0  1

ALTRE OPERAZIONI SUI VETTORI

unique

Ritorna un vettore con gli elementi univoci:

x <- c(1, 3, 3, 3, 4, 4, 5)
x
## [1] 1 3 3 3 4 4 5
unique(x)
## [1] 1 3 4 5
duplicated

Ritorna un vettore logico che indica se l'elemnto e' duplicato.

duplicated(x)

Ritorna un vettore con tutti gli elementi che hanno duplicazioni:

unique(x[duplicated(x)])
## [1] 3 4
rev

Rovescia gli elementi

y <- c(2, 7, 4, 1)
y
## [1] 2 7 4 1
rev(y)
## [1] 1 4 7 2
sort

Ordina gli elementi

sort(y)
## [1] 1 2 4 7
Ordinare in modo decrescente
rev(sort(y))
## [1] 7 4 2 1
Sommare gli elementi
sum(y)
## [1] 14
sum(y[y > 2])
## [1] 11

Differente da:

sum(y > 2)
## [1] 2

Che risponde alla domanda: “Quanti elementi nel vettore y sono maggiori di 2?”

VALORI MANCANTI: NA (Not Available)

NA e' il valore predefinito per gestire i dati mancanti. Indica l'assenza di qualsiasi valore (non e' 0) e puo' essere inseito in ogni tipo di vettore (Ricorda che i vettori contengono un solo tipo di dato).

La presenza di NA un un vettore renderebbe impossibile qualsiasi calcolo: se non abbiamo il valore, non possiamo sapere il risultato dell'operazione matematica che lo coinvolge.

Per sapere se un vettore/oggetto in R contiene degli NA usiamo la funzione is.na()

x <- c(NA, 1, 3, 5, 7)
x
## [1] NA  1  3  5  7
is.na(x)
## [1]  TRUE FALSE FALSE FALSE FALSE
which(is.na(x))
## [1] 1

Per rimuovere gli NA possiamo usare indici e l'operatore ! (NOT)

x[!is.na(x)]
## [1] 1 3 5 7

Molti dei comandi in R prevedono la possibilita' di trattare separatamente gli NA:

mean(x)
## [1] NA

Rimuoviamo gli NA con l'argomento na.rm=TRUE

mean(x, na.rm = TRUE)
## [1] 4

VETTORI: OPERAZIONI ALGEBRICHE help(Arithmetic)

Consideriamo i seguenti vettori:

x <- 4
y <- c(2, 7, 4, 1)

x + y
## [1]  6 11  8  5
x - y
## [1]  2 -3  0  3
x * y
## [1]  8 28 16  4
x/y
## [1] 2.0000 0.5714 1.0000 4.0000

Divisione intera

x%/%y
## [1] 2 0 1 4

Modulo (resto)

x%%y
## [1] 0 4 0 0

Elevare a potenza:

y^2
## [1]  4 49 16  1

FACTORS

Dati qualitativi su scala ordinale o nominale vengono gestiti dalla classe factor.

classi <- c("giovane", "adulto", "vecchio")
classi
## [1] "giovane" "adulto"  "vecchio"
class(classi)
## [1] "character"

Creiamo un vettore:

vettore <- rep(classi, c(10, 5, 7))
vettore
##  [1] "giovane" "giovane" "giovane" "giovane" "giovane" "giovane" "giovane"
##  [8] "giovane" "giovane" "giovane" "adulto"  "adulto"  "adulto"  "adulto" 
## [15] "adulto"  "vecchio" "vecchio" "vecchio" "vecchio" "vecchio" "vecchio"
## [22] "vecchio"
class(vettore)
## [1] "character"

Convertiamolo in un fattore su scala ordinale:

x <- factor(vettore, levels = classi, ordered = T)
x
##  [1] giovane giovane giovane giovane giovane giovane giovane giovane
##  [9] giovane giovane adulto  adulto  adulto  adulto  adulto  vecchio
## [17] vecchio vecchio vecchio vecchio vecchio vecchio
## Levels: giovane < adulto < vecchio
as.integer(x)
##  [1] 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3

AIUTO! R CONVERTE I MIEI NUMERI IN FATTORI

data <- read.table("data.csv", header = TRUE, sep = ",")
data
##   recipe_type   State Successes Attempts
## 1      paper1 alabama       N/A     3079
## 2      paper2 alabama        58     3179
data[, 3]
## [1] N/A 58 
## Levels: 58 N/A
data[, 3] <- as.numeric(as.character(data[, 3]))
## Warning: NAs introduced by coercion
data[, 3]
## [1] NA 58

MATRICI

Una matrice puo' essere definita come un quadro di numeri in cui ciascun elemento e' univocamente individuato da una coppia di numeri interi, che costituiscono l’indice di riga e quello di colonna.

x <- matrix(1:10, ncol = 5)  #costruisci una matrice
x
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    3    5    7    9
## [2,]    2    4    6    8   10
x[, 1]  #seleziona la prima colonna
## [1] 1 2
x[2, ]  #seleziona la seconda riga
## [1]  2  4  6  8 10
x[3, 2]  #seleziona l’elemento [3,2]
## Error: subscript out of bounds
x[2, 3]  #seleziona l’elemento [2,3]
## [1] 6
x[, 4:5]  #seleziona solo le colonne 4 e 5
##      [,1] [,2]
## [1,]    7    9
## [2,]    8   10
x[, -c(2, 4)]  #seleziona le colonne 1, 3 e 5
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10

La funzione matrix() viene utilizzata per costruire una matrice e richiede come argomenti gli elementi che devono costituire la matrice stessa ed il numero delle colonne possibilmente coerente con il primo argomento: ad esempio scrivere

matrix(1:10, nrow = 4, ncol = 3)
## Warning: data length [10] is not a sub-multiple or multiple of the number
## of rows [4]
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7    1
## [4,]    4    8    2

non e' una espressione corretta

Ulteriori funzioni utili per la costruzioni di matrici sono cbind(), rbind() e diag()

CBIND e RBIND

cbind(1:2, c(1, -2), c(0, 9))
##      [,1] [,2] [,3]
## [1,]    1    1    0
## [2,]    2   -2    9
rbind(1:2, c(1, -2), c(0, 9))
##      [,1] [,2]
## [1,]    1    2
## [2,]    1   -2
## [3,]    0    9

DIAG: matrice diagonale

x[, 4:5]
##      [,1] [,2]
## [1,]    7    9
## [2,]    8   10
diag(x[, 4:5])
## [1]  7 10

Costruisci una matrice diagonale

X <- diag(1:3)
X
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    2    0
## [3,]    0    0    3

La funzione solve() consente di risolvere sistemi di equazioni lineari, ma puo anche essere utilizzata per il calcolo della matrice inversa

solve(X)
##      [,1] [,2]   [,3]
## [1,]    1  0.0 0.0000
## [2,]    0  0.5 0.0000
## [3,]    0  0.0 0.3333

DIM

A differenza dei vettori, la dimensione di una matrice e caratterizzata da una coppia di numeri, e la funzione dim()e utilizzata per restituire il numero di righe e colonne:

dim(x)  #dimensione della matrice
## [1] 2 5
dim(x)[1]  #numero di righe
## [1] 2

INIZIALIZZAZIONE E RIEMPIMENTO

ma <- matrix(, nrow = 3, ncol = 4)
ma
##      [,1] [,2] [,3] [,4]
## [1,]   NA   NA   NA   NA
## [2,]   NA   NA   NA   NA
## [3,]   NA   NA   NA   NA

Riempimento:

ma[] <- 1:12
ma
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12

MATRICE TRASPOSTA

t(x)
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
## [3,]    5    6
## [4,]    7    8
## [5,]    9   10

LISTE

In R una list (elenco o lista) e' una raccolta di altri oggetti, anche differenti tra loro, comprese altre liste.

Una lista puo' essere creata con il comando list() ed il numero degli oggetti che la costituiscono definisce la dimensione della lista, mentre le sue componenti sono individuate con semplici [] o doppie [[ ]] parentesi quadre:

lista <- list(matrix(1:9, nrow = 3), rep(0, 3), c("buono", "cattivo"))
lista
## [[1]]
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
## 
## [[2]]
## [1] 0 0 0
## 
## [[3]]
## [1] "buono"   "cattivo"
length(lista)  #la sua dimensione
## [1] 3
lista[[3]]  #il suo terzo elemento
## [1] "buono"   "cattivo"
length(lista[[3]])
## [1] 2
lista[[2]] + 2  #un’operazione sul secondo elemento
## [1] 2 2 2
lista[[1]][2, 2]
## [1] 5

l’estrazione di oggetti appartenenti alla lista stessa e semplice e naturalmente consente di trattare ogni singola (sub-)componente come un oggetto separato e indipendente su cui potere effettuare le operazioni (consentite). Se per estrarre gli oggetti della lista si usano le singole (piuttosto che le doppie) parentesi quadre, l’oggetto verra' comunque estratto ma sara' ancora una lista; la funzione unlist() puo' essere utilizzata per ‘rimuovere’ dall’oggetto la struttura della lista:

lista[[3]]  # un vettore
## [1] "buono"   "cattivo"
lista[3]  # una lista
## [[1]]
## [1] "buono"   "cattivo"
length(lista[3])  # non e' 2
## [1] 1
unlist(lista[3])  # uguale a lista[[3]]
## [1] "buono"   "cattivo"

Possiamo dare dei nomi agli elementi di una lista:

names(lista)  #questa lista e' senza nomi
## NULL
names(lista) <- c("uno", "due", "tre")
lista
## $uno
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
## 
## $due
## [1] 0 0 0
## 
## $tre
## [1] "buono"   "cattivo"

Quando i nomi sono stati assegnati e' possibile estrarre ogni elemento della lista invocando direttamente il proprio nome, attraverso il simbolo $ o con le parentesi quadre, la differenza essendo nel tipo di oggetto restituito:

lista$due
## [1] 0 0 0
lista["due"]
## $due
## [1] 0 0 0
is.list(lista)  # e' una lista?
## [1] TRUE

Per le matrici, l’assegnazione di etichette alle righe e o colonne puo' risultare molto utile ed avviene sfruttando liste di nomi in cui ciascuna componente si riferisce ad una dimensione

x
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    3    5    7    9
## [2,]    2    4    6    8   10
dimnames(x)
## NULL
dimnames(x) <- list(c("uno", "due"), c("a", "b", "c", "d", "e"))

DATA FRAME

Il dataframe costituisce forse l’oggetto piu importante di tutto l’ambiente R, almeno in una sua ottica di gestione e analisi dei dati. Il dataframe rappresenta la matrice dei dati in cui ad ogni riga corrisponde una osservazione e ad ogni colonna una variabile.

A DIFFERENZA DELLE MATRICI, PUO' CONTENERE DIVERSI TIPI DI DATO

Ogni elemento di tale lista rappresenta una variabile statistica, per cui length() restituisce il numero delle variabili, mentre names() i rispettivi nomi.

crea un dataframe con una variabile quantitativa ed una qualitativa:

X <- data.frame(a = 1:4, sesso = c("M", "F", "F", "M"))
X
##   a sesso
## 1 1     M
## 2 2     F
## 3 3     F
## 4 4     M
dim(X)  # numero dei casi e di variabili
## [1] 4 2
X$eta <- c(2.5, 3, 5, 6.2)  # aggiungi una variabile di nome eta
X
##   a sesso eta
## 1 1     M 2.5
## 2 2     F 3.0
## 3 3     F 5.0
## 4 4     M 6.2

Nei i data.frame, possiamo usare diversi modi per accedere ai dati:

X[1, ]
##   a sesso eta
## 1 1     M 2.5
X[1, 2]
## [1] M
## Levels: F M
X[, 2]
## [1] M F F M
## Levels: F M
X$sesso
## [1] M F F M
## Levels: F M

Nelle applicazioni e' spesso utile selezionare soltanto una parte del dataframe iniziale usando delle condizioni:

X[X$sesso == "M", "eta"]
## [1] 2.5 6.2
X$sesso[X$eta <= 3]
## [1] M F
## Levels: F M
X[X$eta <= 3, ]
##   a sesso eta
## 1 1     M 2.5
## 2 2     F 3.0

Con gli operatori logici possiamo costruire query complesse:

X[X$eta <= 5 & X$eta > 3, ]  # eta' compresa tra 3 e 5
##   a sesso eta
## 3 3     F   5

Un modo piu diretto per l’utente e' attraverso la funzione subset()

subset(X, subset = (eta < 3 | eta > 5), select = c(a, sesso))
##   a sesso
## 1 1     M
## 4 4     M

DATA IMPORT

see: http://cran.r-project.org/doc/manuals/r-release/R-data.pdf

data <- read.table("data.csv", header = T, , sep = ",")
# fix(data)

NEXT GENERATION R