I tipi di dati in R
Ogni valore in R ha uno tra pochi tipi atomici. Quattro di questi fanno quasi tutto il lavoro:
- double: numeri decimali, come
3.14,-2,1e6. È ciò che R intende con "numeric" ed è il tipo predefinito per qualsiasi numero tu scriva. - integer: numeri interi memorizzati in modo esatto, scritti con il suffisso
L:42L. - character: testo tra virgolette, come
"hello". - logical: i due valori di verità
TRUEeFALSE(piùNA, il valore mancante: vedi i valori mancanti).
Esiste anche complex (2 + 3i) per qualche calcolo occasionale di elaborazione dei segnali; puoi passare anni senza averne bisogno. typeof() ti dice di che tipo è un valore:
Nota la prima riga: un numero semplice è un double anche se sembra intero. typeof(42) è "double"; solo 42L è un intero. Nell'analisi quotidiana la differenza conta raramente, perché R converte dall'uno all'altro in silenzio, ma spiega molti output di typeof() che altrimenti confonderebbero.
typeof() contro class(): perché non sono d'accordo
R ha due funzioni che sembrano entrambe rispondere a "che cos'è questo?", e rispondono a domande leggermente diverse.
typeof()riporta il tipo di memorizzazione: come il valore sta in memoria.class()riporta il tipo di comportamento: l'etichetta che il meccanismo di dispatch dei metodi di R usa per decidere, per esempio, qualeprintosummaryeseguire.
Per i valori semplici le risposte differiscono solo nel vocabolario:
typeof() dice double (la memorizzazione), class() dice numeric (il comportamento). Con le strutture la distanza aumenta:
La matrice è memorizzata come un semplice vettore di interi, ma si comporta come una matrice: è class() a dire a R di stamparla come una griglia. La stessa divisione compare con i data frame (typeof dice "list", class dice "data.frame") e con le date (typeof dice "double", class dice "Date").
La regola pratica: usa class() quando vuoi sapere cosa è qualcosa nel senso quotidiano, e typeof() quando stai facendo debug di ciò che R fa dietro le quinte.
Controllare i tipi con is.*()
Ogni tipo ha un predicato corrispondente che restituisce TRUE o FALSE, comodo dentro le funzioni che devono validare il proprio input:
Una trappola da conoscere: is.numeric() è TRUE sia per i double sia per gli integer (sono entrambi numeri), ma is.integer() controlla la memorizzazione, quindi è FALSE per un semplice 42:
Se ti sei mai stupito che is.integer(7) sia FALSE per un numero che in senso matematico è ovviamente intero, ecco il motivo. 7 è un double; 7L è un intero.
Convertire i tipi con as.*()
La conversione esplicita usa la famiglia as.*, una funzione per ogni tipo di destinazione:
Due comportamenti da ricordare. as.integer() tronca verso lo zero invece di arrotondare: 7.9 diventa 7. E quando una conversione non ha senso, R non genera un errore; restituisce NA e mostra un warning:
Eseguilo e vedrai NA più un warning "NAs introduced by coercion". È davvero utile: converti un'intera colonna di testo disordinato in numeri e le voci non interpretabili diventano NA invece di far crashare lo script. Ma significa anche che un NA silenzioso può infilarsi nei tuoi dati. Quando una conversione è importante, controlla dopo se sono comparsi nuovi NA.
I valori logici si convertono da e verso i numeri come ti aspetteresti: as.numeric(TRUE) è 1, as.logical(0) è FALSE. Ecco perché sum() di un vettore logico conta i TRUE:
Coercizione implicita: la regola del tipo unico per i vettori
Un vettore atomico in R può contenere un solo tipo. Combina valori misti con c() e R promuove in silenzio tutto al tipo più flessibile presente, seguendo una scala fissa:
logical → integer → double → character
I logici sono diventati 1 e 0, gli interi sono diventati double, e nell'ultima riga tutto è diventato testo: character vince sempre, perché qualsiasi valore si può scrivere come stringa. Puoi confermarlo con typeof():
La coercizione è la causa numero uno dei bug del tipo "perché la mia colonna è testo?": una sola stringa "N/A" sparsa in una colonna di numeri forza l'intero vettore a character. Quando succede, correggi prima il valore colpevole, poi riconverti con as.numeric().
Cosa ti porti a casa
- Quattro tipi di uso quotidiano: double ("numeric"), integer (
42L), character, logical. typeof()= come è memorizzato;class()= come si comporta.3.14è undoubleche si comporta comenumeric.- Controlla con
is.numeric()e simili; converti conas.numeric()e simili. Le conversioni fallite dannoNAcon un warning, non un errore. - I vettori contengono un solo tipo; mescolare forza la coercizione lungo logical → integer → double → character.
Prossimo passo: uno sguardo più da vicino ai tipi numerici, con arrotondamenti, funzioni matematiche e le sorprese della virgola mobile comuni a tutti i linguaggi.
Domande frequenti
Quali sono i tipi di dati di base in R?
I tipi atomici sono double (numeri decimali, quello che R chiama "numeric"), integer (numeri interi scritti con il suffisso L, come 42L), character (testo tra virgolette), logical (TRUE/FALSE) e il raramente usato complex. Tutto ciò che è più grande, vettori, data frame, liste, è costruito a partire da questi.
Qual è la differenza tra typeof() e class() in R?
typeof() riporta come un valore è memorizzato (il suo tipo di basso livello); class() riporta come il valore si comporta, e questo decide quali metodi R richiama. Per un semplice decimale cambiano solo le parole, typeof(3.14) è "double" mentre class(3.14) è "numeric", e per strutture come i data frame typeof() dice "list" mentre class() dice "data.frame".
Come si convertono i tipi in R?
Usa la famiglia as.*: as.numeric("3.5") dà 3.5, as.character(42) dà "42", as.integer(7.9) tronca a 7. Quando una conversione è impossibile, R restituisce NA e mostra un warning invece di un errore: as.numeric("abc") è NA.
Cos'è la coercizione in R?
Quando combini tipi diversi in un solo vettore, R converte tutto in silenzio nel tipo più flessibile, seguendo l'ordine logical → integer → double → character. Quindi c(1, 2, "three") diventa un vettore character: "1" "2" "three".