Data Analytics

Intro R Tipi Dati Strutture

Introduzione ad R
RCode1IntroR_TipiDati-Strutture.R
#  Introduzione a R — Tipi di Dati, Strutture e Vettori
#  Vincenzo Gioia e Gioia Di Credico


# 1. TIPI DI DATI ---- 

## Numeric ----
a <- 10
b <- 3 / 10                 # b vale 0.3
c <- a * (a + b) / (a - b)  # operazione aritmetica

str(a)  # Visualizziamo tipo e struttura oggetto
str(b)
c       # Stampa il risultato

help("+")   # apre la documentazione degli operatori aritmetici
help("str") # apre la documentazione di str()

a.1 <- 1
a.1

# A    # ❌ ERRORE: l'oggetto A non esiste
# 1a <- 1  # ❌ ERRORE: non può iniziare con un numero


## Character ----
d <- "1"
e <- "2"
# d + e  # ❌ ERRORE: non puoi sommare stringhe

s <- "Ciao"
str(s)

# Concatenare stringhe con paste() / paste0()
paste("Ciao", "mondo")                  # considera spaziatura
paste("Ciao", "mondo", sep = "")        # rimuovere la spaziatura
paste("Ciao", "mondo", sep = "-")       # separare con trattino
paste0("Ciao", "mondo", ".txt")         # non considera spaziatura


## Integer ----
var     <- 2   # tipo: numeric (double)
var.int <- 2L  # tipo: integer

str(var)
str(var.int)


## Logical ----
x <- TRUE
y <- F

x + y   # (1 + 0)
2 * x   # (2 * 1)
str(x)

## Verifica e conversione tipo ----
var     <- 3
var.int <- 3L
s <- "Hello"
x <- FALSE

is.integer(var)
is.integer(var.int)
is.numeric(var)
is.numeric(var.int)
is.character(s)
is.logical(x)

as.numeric("3.14")   # → 3.14
as.integer(3.7)      # → 3 (troncamento, NON arrotondamento)
as.character(100)    # → "100"
as.numeric(FALSE)    # → 0
as.logical(0)        # → FALSE
as.logical(1)        # → TRUE
as.numeric("hello")  # → NA + Warning (non convertibile)


## Esercizio 1 ----
# prevedi il risultato prima di eseguire
as.integer(3.9)       # 3 → troncamento, non arrotondamento
as.numeric("abc")     # NA → con Warning
as.logical("TRUE")    # TRUE
as.character(3.14)    # "3.14"


# 2. VETTORI ---- 
db_v <- c(10, 15, 6.4, 3, 18)   # numeric
int_v <- c(1L, 6L, 10L)          # integer
log_v <- c(TRUE, FALSE, T, F)    # logical
ch_v  <- c("A", "B", "C")        # character

str(db_v)
str(int_v)
str(log_v)
str(ch_v)

# Coercizione automatica
str(c(TRUE, 1L))           # → tutto diventa integer
str(c(TRUE, 1L, 2))        # → tutto diventa numeric
str(c(TRUE, 1L, 2, "a"))   # → tutto diventa character!


## Sequenze ----

# Operatore : (il più veloce)
x <- 1:10
x

# seq() — più flessibile
seq(from = 1, to = 10)              # passo 1 (default)
seq(from = 1, to = 10, by = 3)      # passo 3
seq(from = 1, to = 10, length = 5)  # 5 valori equidistanti

# rep() — per ripetizioni
rep(1, 15)                    # 15 volte il valore 1
rep(c("a", "b"), times = 5)   # "a" "b" "a" "b" ...
rep(c("a", "b"), each = 5)    # "a" "a" "a" "a" "a" "b" "b" ...


## Esercizio 2 ----
# genera "file1.txt" "file2.txt" "file3.txt"
paste("file", 1:3, ".txt", sep = "")


## Subsetting ----
a <- c(c(rep(2, 3), 4, 5, rep(1, 5), 11:15))
a

a[6]        # sesto elemento
a[2:4]      # dal secondo al quarto
a[c(2, 5)]  # secondo e quinto

x <- c(1, 2, 4, 8, 16, 32)
x[-4]       # tutti tranne il quarto (x non cambia)
x           # x è ancora intatto
x <- x[-4]  # sovrascrittura: ora x è cambiato
x


## Selezione con condizioni logiche ----
x <- 0:7

x >= 7
x < 5
x >= 7 | x < 5   # OR
x >= 3 & x <= 6  # AND

x.or  <- x[x >= 7 | x < 5]
x.or
x.and <- x[x >= 3 & x <= 6]
x.and


## Operazioni su vettori ----
x <- 1:10
x * 2    # moltiplica ogni elemento per 2
x^2      # quadrato di ogni elemento


## Recycling ----
x <- rep(10, 8)
y <- c(1, 2)
z <- c(1, 2, 3)
x * y   # y riciclato: 10*1, 10*2, 10*1, 10*2
x * z   # lunghezze non multiple → Warning


### Esercizio 3 ----
y <- c(8, 3, 5, 7, 6, 6, 8, 9, 2)
all(y < 5)    # FALSE → non tutti sono < 5
y < 5         # vettore logico: dove è TRUE?
z <- y[y < 5] # → 3 2
z

### Esercizio 4 ----
y <- c(TRUE, TRUE, FALSE)
z <- 1 * y   # coercizione: TRUE→1, FALSE→0
z            # → 1 1 0
y + 0        # stessa coercizione

### Esercizio 5 ----
y <- c(TRUE, TRUE, FALSE)
y * runif(3)
# I logici vengono convertiti in 0/1 prima della moltiplicazione.
# TRUE=1 → moltiplicato per un numero casuale tra 0 e 1
# FALSE=0 → risultato sempre 0

## OPERATORI LOGICI: ----
x <- 0:7
all(x > 0)   # FALSE → x contiene 0
any(x < 0)   # FALSE → nessun elemento negativo
all(x >= 0)  # TRUE  → tutti >= 0
any(x <= 0)  # TRUE  → x contiene 0


## FUNZIONI STATISTICHE UTILI ----
x <- 3:22
length(x)  # numero di elementi
sum(x)     # somma
mean(x)    # media
max(x)     # massimo
min(x)     # minimo
range(x)   # c(minimo, massimo)
prod(x)    # prodotto di tutti gli elementi

x[20] <- 2
x
sort(x)                      # ordina in modo crescente
sort(x, decreasing = TRUE)   # ordina in modo decrescente
order(x)                     # restituisce gli INDICI che ordinerebbero x

# Funzioni su vettori logici
x <- c(FALSE, FALSE, TRUE)
sum(x)    # 1  → conta i TRUE
mean(x)   # 0.333... → proporzione di TRUE


# NOMI DEGLI ELEMENTI
x <- c(a = 1, b = 2, c = 3) # Metodo 1
x

x <- 1:3
names(x) <- c("a1", "b1", "c1") # Metodo 2
x

x["a1"]       # → a1 = 1
names(x)[2]   # → "b1"

### Esercizio 6 ---- 
set.seed(123)
x <- sample(10) < 4
x
which(x)    # restituisce le POSIZIONI dove x è TRUE

### Esercizio 7 ----
y <- c(9, 2, 3, 9, 4, 10, 4, 11)
sum(sort(y, decreasing = TRUE)[1:3])   # → 30
y_ord <- rev(sort(y))
sum(y_ord[1:3])                        # → 30

### Esercizio 8 ----
x <- 1:4
x[c(TRUE, TRUE, NA, FALSE)]
# → 1 2 NA

# MATRICI ----
x <- matrix(c(2, 3, 5, 7, 11, 13), nrow = 3)
x

x <- matrix(c(2, 3, 5, 7, 11, 13), ncol = 3)
x

mx <- matrix(c(2, 3, 5, 7, 11, 13), ncol = 3, byrow = TRUE)
mx

# Dimensioni e nomi
nrow(mx)
ncol(mx)
dim(mx)
dim(mx)[1]

rownames(mx) <- c("A", "B")
colnames(mx) <- c("a", "b", "c")
mx

# Subsetting
mx[2, 1]
mx[2, 2]
mx[2, ]
mx["B", ]
mx[, 3]
mx[, "c"]
mx[, c("a", "b")]

x <- matrix(1:16, ncol = 4)
x
y <- x[c(1, 4), 2:4]
y

z <- x[-c(1:2), -1]
z

### Esercizio 9 (matrici) ---- 
m <- matrix(1:9, nrow = 3, byrow = TRUE)
m[2, 3]   # → 6
m[, 2]    # → 2 5 8
m[1, ]    # → 1 2 3

## ALGEBRA LINEARE ----
y <- c(1.2, 3, 0.4, 10)
2 * y

crossprod(c(1, 2, 3), c(0, 12, 13))  # prodotto scalare
m <- c(1, 2, 3) %*% c(0, 12, 13)
m
is.matrix(m)

a <- matrix(c(1, 2, 3, 4), ncol = 2, byrow = TRUE)
b <- matrix(c(1, -1, 0, 1), ncol = 2, byrow = TRUE)
a
b
a * b
a %*% b
crossprod(a, b)
tcrossprod(a, b)

# Benchmark (eval = FALSE nel documento originale)
X <- matrix(runif(100000), 50)
system.time(crossprod(X))
system.time(t(X) %*% X)

# Inversa e sistemi lineari
a <- matrix(c(1, 1, -1, 1), nrow = 2, ncol = 2)
a
solve(a)
b <- c(2, 4)
solve(a, b)

# Funzioni utili
diag(a)
diag(b)
diag(3)
det(a)

## Esercizio 10 ----
A <- matrix(c(2, 1, 5, 3), nrow = 2, byrow = TRUE)
b <- c(1, 2)
solve(A)
A %*% solve(A)
solve(A, b)

# ARRAY ----
x <- 1:20
a.x <- array(x, dim = c(5, 2, 2))
a.x
dim(a.x)

a.x[3, 2, 1]
a.x[, 2, ]
a.x[-1, , 1]

# Matrice vs Vettore vs Array
str(2:4)
y <- matrix(2:4, nrow = 1)
y
str(y)

y <- matrix(2:4, ncol = 1)
y
str(y)

a <- matrix(1:6, ncol = 3, nrow = 2)
is.matrix(a)
is.array(a)

b <- a[, 2]
str(b)
is.vector(b)
is.matrix(b)
dim(b)
as.matrix(b)


# Liste ----
x1 <- 1:3
x2 <- c("A", "B", "C", "D", "E")
x3 <- matrix(1:12, nrow = 3)

mylist <- list(x1, x2, x3)
str(mylist)

## Selezione degli elementi ----
mylist[[1]]
mylist[[2]][3]
mylist[[3]]
mylist[[3]][1, 1]

l1 <- mylist[[1]]
l1[2]
mylist[[1]][2]

## Esercizio rapido ----
# prime due righe e prime tre colonne della matrice in posizione 3
mylist[[3]][1:2, 1:3]

## Liste con nomi ----
mylist2 <- list(comp1 = x1, comp2 = x2, comp3 = x3)

mylist2$comp1
mylist2$comp2[3]
mylist2[["comp1"]]

## Aggiungere elementi e unire liste ----
x <- list()
x[[1]] <- x1
x[[4]] <- "questo è il quarto elemento della lista x"
str(x)

newlist <- c(mylist, mylist2)
is.list(newlist)
str(newlist)

names(mylist) <- c("A", "B", "C")
names(mylist2)

newlist <- c(mylist, mylist2)
newlist[[1]]
newlist$A
newlist[["A"]]

## Valori speciali ----

0 / 0           # NaN
1 / 0           # Inf
a <- -1 / 0
a               # -Inf
a - a           # NaN
as.numeric("a") # NA (con Warning)


# Fattori ----
country <- c("Italia", "Germania",
             "Francia", "Germania",
             "Germania", "Germania",
             "Francia", "Italia", 
             "Italia", "Francia")
str(country)

countryf <- factor(country)
str(countryf)
is.factor(countryf)
levels(countryf)

## Confronto tra character e factor ----
cbind(country, countryf)

## Modificare l'ordine dei livelli ----
a <- relevel(countryf, "Italia")
a

factor(country,
       levels = c("Italia", "Germania", "Francia"))

factor(country, labels = c("FR", "GE", "IT"))

factor(country,
       levels = c("Italia", "Germania", "Francia"),
       labels = c("IT",     "GE",       "FR"))

# Modificare levels() direttamente rinomina le etichette
countryf2 <- countryf
levels(countryf)
levels(countryf2) <- c("Italia", "Germania", "Francia")
cbind(countryf, countryf2)
cbind.data.frame(countryf, countryf2)

## Funzioni utili sui fattori ----

age <- c(47, 44, 44, 40, 38, 36, 42, 34, 34, 44)
tapply(age, countryf, mean)

gender <- c(1, 1, 2, 1, 1, 2, 1, 2, 2, 2)
genderf <- factor(gender)
genderf
levels(genderf)
levels(genderf) <- c("F", "M")
str(genderf)

## Esercizio 11 ---- 
# Crea una lista con tre componenti: un vettore numerico, una stringa e una matrice 2x2.
# Assegna nomi ai componenti e accedi a ciascuno in almeno due modi diversi.
mylist3 <- list(
  numeri  = c(1.5, 2.5, 3.5),
  testo   = "ciao",
  matrice = matrix(1:4, nrow = 2)
)
mylist3$numeri
mylist3[["numeri"]]
mylist3[[2]]
mylist3$testo
mylist3[[3]][1, 2]
mylist3$matrice[1, 2]

## Esercizio 12 ----
# Definisci x <- c(5, 12, 13, 12). Converti in factor e ispeziona la struttura.
x <- c(5, 12, 13, 12)
xf <- factor(x)
str(xf)
levels(xf)  # → "5" "12" "13"

## Esercizio 13 ----
# Crea un factor da c("1","1","0","1","1","0"). Cosa restituiscono length() e mode()?
x <- c("1", "1", "0", "1", "1", "0")
xf <- factor(x)
length(xf)  # → 6
mode(xf)    # → "numeric"
str(xf)

## Esercizio 14 ----
# Assegna etichette "f" e "m" ai livelli "0" e "1". Cosa produce table()?
x2 <- factor(x, levels = c("1", "0"), labels = c("f", "m"))
x2
table(x2)

## Esercizio 15 ----
# Cosa succede a v1 quando modifichi i livelli? In cosa differisce v2 da v1?
v1 <- factor(letters[1:5])
levels(v1) <- rev(levels(v1))
# v1: i livelli vengono RINOMINATI (a→e, b→d, ...)

v2 <- factor(letters[1:5], levels = rev(letters[1:5]))
# v2: cambia l'ORDINE dei livelli, le etichette restano invariate

v1
v2