0Pricing
R Academy · Lezione

Valutazione tidy: {{ }} e .data

Scriva funzioni dplyr che accettano in sicurezza nomi di colonne come argomenti.

Valutazione tidy: {{ }} e .data è una lezione R Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento R Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso R Academy include 4 lezioni in totale.

Il problema: programmare con dplyr

dplyr utilizza la valutazione non standard (NSE): i nomi delle colonne vengono passati senza virgolette. Questo è pratico nell'uso interattivo, ma può essere complesso quando si scrivono funzioni. Come si passa il nome di una colonna come variabile a una funzione di dplyr?

library(dplyr)

df <- data.frame(x=1:5, y=c(2,4,6,8,10))

# Works fine interactively:
df %>% summarize(mean_x = mean(x))

# But what if 'x' is a variable?
col_name <- 'x'
# df %>% summarize(result = mean(col_name))  # WRONG! treats 'col_name' as column
cat('Need tidy evaluation to solve this!')

L'operatore {{ }} embrace

All'interno di una funzione, utilizzi {{ col_var }} (chiamato «curly-curly» o «embrace») per passare un nome di colonna che verrà valutato nel contesto del data frame. Questo è l'approccio consigliato per la maggior parte della programmazione di funzioni dplyr.

library(dplyr)

df <- data.frame(
  group = c('A','A','B','B'),
  sales = c(100, 120, 200, 180),
  costs = c(60, 70, 110, 90)
)

# Function using {{ }}
group_mean <- function(data, group_col, value_col) {
  data %>%
    group_by({{ group_col }}) %>%
    summarize(mean_val = mean({{ value_col }}), .groups = 'drop')
}

group_mean(df, group, sales)
group_mean(df, group, costs)

{{ }} per i nomi delle colonne nell'output

È possibile utilizzare {{ }} anche a sinistra di := per assegnare dinamicamente un nome alle colonne di output. L'operatore := (operatore walrus) consente di usare nomi variabili a sinistra delle assegnazioni all'interno dei verbi dplyr.

library(dplyr)

df <- data.frame(a=1:4, b=c(2,4,6,8))

# Dynamic output column name
compute_mean <- function(data, col) {
  col_name <- paste0('mean_', deparse(substitute(col)))
  data %>% summarize('{col_name}' := mean({{ col }}))
}

compute_mean(df, a)
compute_mean(df, b)

Il pronome .data

.data[['col_name']] consente di selezionare una colonna usando una variabile stringa. Indica esplicitamente a dplyr di cercare la colonna nel data frame corrente. È utile quando si hanno i nomi delle colonne sotto forma di stringhe di caratteri.

library(dplyr)

df <- data.frame(
  name = c('Alice','Bob','Carol'),
  score = c(85, 92, 78),
  grade = c('B','A','C')
)

# Using .data with a string variable
get_summary <- function(data, col_name) {
  data %>%
    summarize(
      n = n(),
      mean_val = mean(.data[[col_name]])
    )
}

get_summary(df, 'score')

across() — Applicare a più colonne

across(cols, fns), usato all'interno di mutate() o summarize(), applica una funzione a più colonne contemporaneamente. Selezioni le colonne con gli helper tidyselect: starts_with(), where(is.numeric), everything(), ecc.

library(dplyr)

df <- data.frame(
  id = 1:3,
  sales_q1 = c(100, 200, 150),
  sales_q2 = c(120, 180, 160),
  cost_q1 = c(60, 110, 80),
  cost_q2 = c(70, 100, 85)
)

# Summarize all numeric columns except 'id'
df %>%
  summarize(across(where(is.numeric) & !id, mean))

across() con funzioni denominate

Passi ad across() un elenco denominato di funzioni per calcolare più statistiche per ogni colonna. Le colonne di output vengono denominate come col_fn. Utilizzi .names per personalizzare lo schema dei nomi.

library(dplyr)

df <- data.frame(
  x = c(10, 20, 30, 40),
  y = c(5, 15, 25, 35)
)

# Compute mean and sd for both columns
df %>%
  summarize(across(
    c(x, y),
    list(mean = mean, sd = sd),
    .names = '{.col}_{.fn}'
  ))

across() in mutate()

L'uso di across() all'interno di mutate() trasforma più colonne simultaneamente. In questo modo si evita di ripetere la stessa trasformazione per ogni singola colonna.

library(dplyr)

df <- data.frame(
  id = 1:3,
  revenue = c(1000, 2000, 1500),
  cost = c(600, 1100, 800),
  tax = c(100, 200, 150)
)

# Round all numeric columns except id to nearest 10
df %>%
  mutate(across(where(is.numeric) & !id,
                ~round(., -2)))

pick() — Selezionare colonne per le operazioni

pick() (dplyr 1.1+) seleziona un sottoinsieme di colonne come mini data frame, utile per passarlo a funzioni che si aspettano un data frame. Funziona all'interno di mutate() e summarize().

library(dplyr)

df <- data.frame(
  id = 1:3,
  a = c(1, 2, 3),
  b = c(4, 5, 6),
  c_val = c(7, 8, 9)
)

# Use pick() to compute row-wise mean across selected columns
df %>%
  mutate(
    row_mean = rowMeans(pick(a, b, c_val)),
    row_max = do.call(pmax, pick(a, b, c_val))
  )

Scrivere funzioni dplyr riutilizzabili

La combinazione di {{ }}, .data[[]] e across() consente di scrivere potenti funzioni di analisi riutilizzabili. Lo schema fondamentale è accettare i nomi delle colonne come argomenti senza virgolette (utilizzando {{ }}) oppure come stringhe (utilizzando .data[[]]).

library(dplyr)

df <- data.frame(
  region = c('East','East','West','West'),
  product = c('A','B','A','B'),
  revenue = c(100, 200, 150, 250),
  units = c(10, 15, 12, 20)
)

# Flexible grouped summary function
group_stats <- function(data, ..., metric) {
  data %>%
    group_by(...) %>%
    summarize(
      total = sum({{ metric }}),
      average = mean({{ metric }}),
      .groups = 'drop'
    )
}

group_stats(df, region, metric = revenue)
group_stats(df, region, product, metric = units)

Helper per la selezione tidy

Gli helper tidyselect funzionano all'interno di across(), select() e pick(): starts_with(), ends_with(), contains(), matches(), num_range(), where(predicate) ed everything().

library(dplyr)

df <- data.frame(
  id = 1:3,
  score_2022 = c(80,85,90),
  score_2023 = c(82,88,91),
  score_2024 = c(85,90,93),
  category = c('A','B','A')
)

# Select all score columns and compute their means
df %>%
  summarize(
    across(starts_with('score'), mean),
    n = n()
  )

Combinare gli schemi di tidy evaluation

Le funzioni dplyr del mondo reale spesso combinano {{ }} per le variabili di raggruppamento, across() per più metriche e .data[[]] per i nomi delle colonne sotto forma di stringhe. Capire quando utilizzare ciascuno schema rende il codice flessibile e corretto.

library(dplyr)

df <- data.frame(
  dept = c('HR','HR','Eng','Eng'),
  salary = c(60000, 65000, 100000, 110000),
  bonus = c(5000, 6000, 15000, 18000)
)

# String-based column selection with .data
summarize_column <- function(data, group_col, value_col_name) {
  data %>%
    group_by(.data[[group_col]]) %>%
    summarize(
      mean = mean(.data[[value_col_name]]),
      total = sum(.data[[value_col_name]]),
      .groups = 'drop'
    )
}

summarize_column(df, 'dept', 'salary')
summarize_column(df, 'dept', 'bonus')

Verifica rapida

All'interno di una funzione personalizzata, qual è il modo corretto per passare a dplyr il nome di una colonna come argomento senza virgolette?

Riepilogo: tidy evaluation

Punti chiave sulla programmazione con dplyr:

  • {{ col }} — incorpora nelle funzioni gli argomenti con nomi di colonna senza virgolette
  • .data[['col_name']] — accede alle colonne tramite il nome della variabile stringa
  • := operatore walrus — utilizzalo con {{ }} o con stringhe glue per nomi di output dinamici
  • across(cols, fns) — applica una o più funzioni a più colonne contemporaneamente
  • pick(cols) — seleziona colonne come sotto-data-frame per operazioni riga per riga
  • Helper tidyselect: starts_with(), where(), contains(), everything()
library(dplyr)

df <- data.frame(
  group = c('A','A','B','B'),
  v1 = c(10, 20, 30, 40),
  v2 = c(5, 15, 25, 35)
)

# Reusable function using {{ }} + across
group_summary <- function(data, grp) {
  data %>%
    group_by({{ grp }}) %>%
    summarize(across(where(is.numeric), list(mean=mean, sum=sum)), .groups='drop')
}

group_summary(df, group)

Domande Frequenti

La lezione «Valutazione tidy: {{ }} e .data» è gratuita?

Sì — il testo completo di «Valutazione tidy: {{ }} e .data» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso R Academy, passa a CoddyKit PRO. Il corso R Academy include 4 lezioni in totale.

Cosa imparerò in «Valutazione tidy: {{ }} e .data»?

Scriva funzioni dplyr che accettano in sicurezza nomi di colonne come argomenti. Eserciti R Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare R Academy?

Non è richiesta alcuna esperienza precedente. R Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Valutazione tidy: {{ }} e .data»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione R Academy?

Sì. Ogni lezione R Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Riepiloghi raggruppati e group_by()
  2. Funzioni finestra: lag, lead, cumsum
  3. Join tra più tabelle in dplyr
  4. Valutazione tidy: {{ }} e .data
← Torna a R Academy