Menu

Aggiungere e trasformare colonne in R (mutate e R base)

Come aggiungere, trasformare ed eliminare colonne di un data frame: df$new <- ..., ifelse() per colonne condizionali, transform() e mutate() di dplyr con case_when().

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Aggiungere una colonna: df$new <- value

Per aggiungere una colonna in R base, assegna a un nome che non esiste ancora. Il valore di solito è calcolato da colonne che esistono già:

Sono successe due cose. orders$total ha ricevuto un vettore completo: price * qty viene calcolato per tutte le righe in una volta, perché in R l'aritmetica è vettorizzata. orders$currency ha ricevuto un singolo valore, che R ha riciclato su tutte e quattro le righe. Qualsiasi altra lunghezza è un errore (replacement has 3 rows, data has 4): è R che ti protegge da una colonna disallineata.

Funziona perché un data frame è una lista di colonne della stessa lunghezza: assegnare un nuovo elemento con nome fa crescere la lista. La guida ai data frame spiega questo modello nel dettaglio.

Colonne condizionali: ifelse()

Una colonna il cui valore dipende da una condizione vuole ifelse(), il cugino vettorizzato di if. Prende un intero vettore di condizioni e restituisce un valore per riga:

Perché non un semplice if? Perché if valuta esattamente un TRUE/FALSE: se gli passi una colonna, dà errore (the condition has length > 1). ifelse(test, yes, no) controlla ogni elemento e sceglie riga per riga. Per tre o più esiti puoi annidare:

Annidare su due livelli va bene; con tre o più diventa una piramide, ed è proprio il lavoro per cui è stato costruito case_when() di dplyr (più sotto). L'if/else su un singolo valore è trattato nella guida a if-else.

Più colonne insieme: transform()

transform() di R base aggiunge più colonne in una sola chiamata, usando i nomi delle colonne senza prefisso:

Nota che transform() restituisce un nuovo data frame: devi riassegnare il risultato, mentre df$new <- ... modifica sul posto. Un limite: le espressioni dentro una stessa chiamata a transform() non si vedono tra loro, quindi discount = ifelse(total > 50, ...) lì non funziona (total non esiste ancora). Fallo in due passaggi, oppure con mutate(), che lo permette.

Modificare o creare

La stessa sintassi di assegnazione sovrascrive una colonna esistente: l'unica differenza è se quella colonna esisteva già o no.

Vale la pena fermarsi su questo punto: R non ti avvisa quando sovrascrivi una colonna. Un errore di battitura come df$prise <- round(df$price, 2) crea in silenzio una nuova colonna invece di correggere quella vecchia. Dopo una trasformazione, usa print() o str() sul data frame e conferma di aver cambiato quello che intendevi.

Eliminare una colonna

Assegna NULL per eliminarla:

La colonna non c'è più, senza cerimonie. Per eliminarne diverse, df[, c("a", "b")] (tieni quelle che elenchi) di solito è più chiaro di tanti NULL ripetuti.

Il modo dplyr: mutate()

Il verbo di dplyr per tutto quanto visto sopra è mutate(). I frammenti qui sotto sono statici, perché la sandbox esegue solo R base, ma ecco come appaiono le stesse operazioni:

library(dplyr)

orders |>
    mutate(
        total    = price * qty,
        big      = total > 50        # can use total, defined one line up
    )

Due vantaggi rispetto a R base. Primo, le colonne definite nello stesso mutate() possono riferirsi l'una all'altra, in ordine, cosa che transform() rifiuta. Secondo, gli helper condizionali sono migliori degli ifelse() annidati:

students |>
    mutate(
        grade = if_else(score >= 60, "pass", "fail"),
        band  = case_when(
            score >= 85 ~ "high",
            score >= 60 ~ "mid",
            .default    = "low"
        )
    )

if_else() è un ifelse() più severo (entrambi i rami devono essere dello stesso tipo, e questo cattura bug reali). case_when() si legge come un elenco piatto di coppie condition ~ value controllate dall'alto in basso, con .default come ripiego: il sostituto leggibile della piramide di ifelse(). Come ogni verbo di dplyr, mutate() restituisce un nuovo data frame; vedi l'introduzione a dplyr per come si concatena con il resto.

Cosa ti porti a casa

  • df$new <- expression aggiunge una colonna; l'espressione viene eseguita per tutte le righe in una volta.
  • ifelse(test, yes, no) costruisce colonne condizionali; un semplice if non può farlo.
  • transform() aggiunge più colonne per chiamata ma non si vedono tra loro; mutate() sì.
  • La stessa assegnazione sovrascrive in silenzio: controlla l'ortografia dopo una trasformazione.
  • df$col <- NULL elimina una colonna; case_when() sostituisce le piramidi di ifelse() annidati.

Prossimo passo: rinominare colonne, con names(), l'idioma robusto di R base, e rename() di dplyr.

Domande frequenti

Come si aggiunge una nuova colonna a un data frame in R?

Assegna a un nome di colonna che non esiste ancora: df$total <- df$price * df$qty. R crea la colonna sul momento. Il valore può essere un singolo valore (riciclato su ogni riga) o un vettore calcolato da altre colonne, purché la sua lunghezza corrisponda al numero di righe.

Come si crea una colonna condizionale in R?

Usa l'ifelse() vettorizzato: df$grade <- ifelse(df$score >= 60, "pass", "fail") controlla tutte le righe in una volta. Non usare un semplice if: gestisce una singola condizione, non una colonna. Per più di due esiti, annida chiamate a ifelse() o usa case_when() di dplyr.

Cosa fa mutate() in R?

mutate() è il verbo di dplyr per aggiungere o trasformare colonne: df |> mutate(total = price * qty) restituisce una copia del data frame con la nuova colonna. Può definire più colonne in una sola chiamata, e le colonne successive possono usare quelle definite prima nello stesso mutate.

Come si elimina una colonna da un data frame in R?

Assegnale NULL: df$notes <- NULL rimuove la colonna sul posto. In dplyr, select(-notes) restituisce una copia senza quella colonna.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA