Cos'è R e chi lo usa davvero
Cos'è il linguaggio R: nato da statistici per statistici, vettoriale, costruito attorno al data frame. Dove domina, dove non ha senso e gli errori tipici.
Ti hanno passato uno script R per rifare un'analisi, oppure il tuo corso di statistica lo dà per scontato, e al primo sguardo sembra scritto da qualcuno che non ha mai visto un altro linguaggio: frecce al posto dell'uguale, indici che partono da uno, tre modi diversi per fare la stessa cosa. Non è un'impressione sbagliata, ed è proprio la chiave per capirlo. In questo articolo trovi cos'è R, perché è fatto così, dove è imbattibile e dove invece non ha senso usarlo.
Cos'è R
R è un linguaggio interpretato pensato per l'analisi statistica e i grafici, nato da statistici per statistici: lavora nativamente su vettori e tabelle di dati, e tratta la statistica come funzionalità di base invece che come libreria aggiunta.
È nato negli anni Novanta all'Università di Auckland, da Ross Ihaka e Robert Gentleman, come implementazione libera di S, un linguaggio statistico sviluppato ai Bell Labs. È open source e i pacchetti si installano da CRAN, il repository ufficiale, che ne raccoglie migliaia.
Nato da statistici, non da programmatori
Questa è la frase che spiega tutto il resto, pregi e stranezze insieme.
Chi ha progettato R non voleva costruire software: voleva uno strumento per esplorare dati in modo interattivo, scrivendo una riga, guardando il risultato e scrivendo la successiva. Le scelte che a un programmatore sembrano bizzarre hanno senso da quel punto di vista.
- Gli indici partono da 1. Per uno statistico la prima osservazione è la numero uno, come nelle formule matematiche.
x[1]è il primo elemento. - L'assegnamento si scrive
<-. È un'eredità di S, nato quando alcune tastiere avevano un tasto dedicato a quella freccia. Anche=funziona quasi sempre, ma la convenzione della comunità resta la freccia. - Esistono tanti modi per fare la stessa cosa. R è cresciuto per accumulo: ogni gruppo di ricerca aggiungeva le funzioni che gli servivano, con i nomi e le convenzioni che preferiva. Non c'è mai stato qualcuno che imponesse uno stile unico.
x <- c(4, 8, 15, 16, 23, 42)
x[1] # 4: il primo elemento
x[0] # numeric(0): nessun errore, un vettore vuoto
x[-1] # tutti tranne il primo, non l'ultimo come in Python
Il rovescio della medaglia è che la statistica è cittadina di prima classe. Una regressione lineare, un test t, un'analisi della varianza sono nella dotazione di base, senza installare niente:
modello <- lm(pressione ~ eta + farmaco, data = studio)
summary(modello)
Quella sintassi con la tilde, risposta ~ predittori, si chiama formula ed è talmente comoda che altri ecosistemi l'hanno copiata. E l'output di summary() è già quello che uno statistico vuole leggere: coefficienti, errori standard, valori p, bontà dell'adattamento.
Un linguaggio vettoriale: il concetto da capire subito
In R non esistono numeri singoli: un numero è un vettore di lunghezza uno. Ogni operazione è pensata per lavorare su vettori interi, elemento per elemento, in un colpo solo.
prezzi <- c(10, 25, 8, 40)
prezzi * 1.22 # IVA applicata a tutti: 12.2 30.5 9.76 48.8
prezzi > 20 # FALSE TRUE FALSE TRUE
prezzi[prezzi > 20] # 25 40
sum(prezzi > 20) # 2: quanti superano la soglia
Nessun ciclo, nessun contatore. Il filtro prezzi[prezzi > 20] usa un vettore di valori logici come indice: è il modo naturale di selezionare dati in R, e una volta capito lo usi ovunque.
Questo stile — descrivere l'operazione sull'insieme invece dei singoli passi — è parente stretto della programmazione funzionale, di cui trovi il quadro generale in paradigmi di programmazione.
Il riciclo è la parte insidiosa. Se sommi due vettori di lunghezza diversa, R ripete il più corto finché non raggiunge la lunghezza dell'altro:
c(1, 2, 3, 4) + c(10, 20) # 11 22 13 24
A volte è esattamente ciò che vuoi. Altre volte è un errore di allineamento dei dati che R esegue senza fiatare, e che scopri solo guardando i risultati.
Il data frame, la struttura centrale
Se il vettore è l'atomo, il data frame è la molecola su cui lavori tutto il giorno: una tabella in cui ogni colonna è un vettore, e ogni colonna può avere un tipo diverso. È l'equivalente di un foglio di calcolo pulito o di una tabella di un database.
pazienti <- data.frame(
id = 1:6,
eta = c(34, 58, 41, 67, 29, 52),
gruppo = c("A", "B", "A", "B", "A", "B")
)
pazienti[pazienti$eta > 40, ] # righe con età sopra 40
mean(pazienti$eta) # età media
La notazione tabella[righe, colonne] e il $ per accedere a una colonna sono il cuore di base R. Se conosci SQL, riconosci subito le operazioni: filtrare, selezionare, raggruppare, unire.
Il tidyverse: il secondo dialetto
Qui c'è una cosa che nessun manuale introduttivo ti dice chiaramente: oggi esistono di fatto due modi di scrivere R.
Il tidyverse è una famiglia di pacchetti — i più noti sono dplyr per manipolare i dati e ggplot2 per i grafici — che condividono una filosofia coerente: nomi di funzioni che sono verbi, un argomento dati sempre in prima posizione, e la pipe per concatenare i passaggi. Lo stesso calcolo nei due dialetti:
# Base R
aggregate(eta ~ gruppo, data = subset(pazienti, eta > 40), FUN = mean)
# Tidyverse
library(dplyr)
pazienti |>
filter(eta > 40) |>
group_by(gruppo) |>
summarise(eta_media = mean(eta))
La seconda versione si legge dall'alto in basso come una frase: prendi i pazienti, filtra, raggruppa, riassumi. È più lunga ma molto più facile da mantenere, ed è il motivo per cui buona parte dei corsi e dei libri recenti insegna direttamente il tidyverse.
La pipe |> è nativa nelle versioni moderne di R; nel codice meno recente trovi %>%, che viene dal pacchetto magrittr e fa quasi la stessa cosa. Saperle riconoscere entrambe ti evita molta confusione quando leggi codice altrui.
I grafici: il vero punto di forza
ggplot2 è probabilmente la ragione singola per cui molte persone restano su R anche quando potrebbero cambiare. Si basa su una "grammatica dei grafici": descrivi quali variabili vanno su quali assi e con quale forma, e aggiungi strati.
library(ggplot2)
ggplot(pazienti, aes(x = gruppo, y = eta, fill = gruppo)) +
geom_boxplot() +
labs(title = "Età per gruppo", x = NULL, y = "Età (anni)") +
theme_minimal()
Il risultato è un grafico con una resa tipografica già adatta a un articolo scientifico, e cambiare tipo di grafico significa sostituire uno strato, non riscrivere tutto.
Dove domina davvero (e dove no)
| Ambito | Adatto? | Perché |
|---|---|---|
| Statistica accademica | Molto | I nuovi metodi escono spesso prima come pacchetto R |
| Ricerca biomedica, bioinformatica | Molto | Bioconductor è lo standard per dati genomici |
| Epidemiologia, salute pubblica | Molto | Modelli di sopravvivenza, dati clinici, tradizione consolidata |
| Grafici pubblicabili | Molto | ggplot2 |
| Report riproducibili | Molto | R Markdown e Quarto mescolano testo, codice e risultati |
| Machine learning in produzione | Poco | L'ecosistema è in Python |
| Applicazioni, backend, API | No | Non è stato pensato per questo, e si vede |
| Software che gira per anni in produzione | No | Gestione di dipendenze e deploy molto più scomoda |
I report riproducibili meritano una nota. Con R Markdown o Quarto scrivi un unico documento che contiene il testo, il codice e i risultati. Quando arrivano dati nuovi, rigeneri il documento e tabelle e grafici si aggiornano da soli. Nel mondo della ricerca, dove qualcuno deve poter rifare esattamente la tua analisi, è un vantaggio enorme.
Esiste Shiny per costruire piccole applicazioni web interattive in R, ed è ottimo per dashboard interne. Ma se il tuo obiettivo è costruire un prodotto software, R è lo strumento sbagliato: lo dicono per primi quelli che lo usano ogni giorno.
Errori comuni
Scrivere cicli come in altri linguaggi. È l'errore di chi arriva da fuori. Un for che scorre un vettore elemento per elemento e lo fa crescere a ogni giro è lento e illeggibile:
# Da evitare
risultato <- c()
for (i in 1:length(prezzi)) {
risultato <- c(risultato, prezzi[i] * 1.22)
}
# In R
risultato <- prezzi * 1.22
I cicli non sono vietati — a volte servono — ma se stai lavorando su un vettore o una colonna, quasi sempre esiste un'operazione vettoriale che fa lo stesso in una riga.
I factor che si comportano in modo inatteso. Un factor è il tipo che R usa per le variabili categoriche: sotto il cofano sono numeri interi con un'etichetta. Il risultato può sorprendere:
f <- factor(c("10", "20", "5"))
as.numeric(f) # 1 2 3: i codici interni, non i valori
as.numeric(as.character(f)) # 10 20 5: quello che volevi
Nelle versioni più vecchie di R, inoltre, le colonne di testo lette da un CSV diventavano factor in automatico. Se lavori su codice datato, è una fonte di bug frequente.
Mescolare base R e tidyverse nello stesso script senza criterio. Entrambi funzionano, ma alternarli riga per riga produce codice che nessuno legge volentieri — incluso te fra sei mesi. Scegli un dialetto come base e usa l'altro solo quando serve davvero.
Usare 1:length(x) su un vettore che può essere vuoto. Se x è vuoto, 1:0 produce 1 0 e il ciclo gira due volte su elementi inesistenti. La forma sicura è seq_along(x).
Dimenticare na.rm = TRUE. Se una colonna contiene un solo valore mancante, mean() restituisce NA. È un comportamento voluto — R non vuole nasconderti i dati mancanti — ma sorprende tutti la prima volta.
In sintesi
R è un linguaggio fatto da statistici per statistici, e questo spiega sia i punti di forza sia le stranezze: indici da uno, <-, più modi per fare ogni cosa, e la statistica disponibile senza installare niente.
Ragiona per vettori e data frame. Chi lo usa come un linguaggio qualunque, a colpi di cicli, combatte contro lo strumento; chi pensa per operazioni sull'insieme lo trova sorprendentemente conciso.
Oggi parla due dialetti, base R e tidyverse: conviene sceglierne uno come principale e saper leggere l'altro.
È imbattibile su statistica, ricerca biomedica, grafici e report riproducibili; è fuori posto nelle applicazioni e nel software di produzione. Se stai decidendo tra R e l'alternativa più diffusa, il confronto diretto è in Python o R.
Se stai pensando di farne un mestiere, la strada completa è in come diventare data scientist; per collocare R tra tutti gli altri linguaggi, la mappa è in tutti i linguaggi di programmazione.