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 dinamiciacross(cols, fns)— applica una o più funzioni a più colonne contemporaneamentepick(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
- Riepiloghi raggruppati e group_by()
- Funzioni finestra: lag, lead, cumsum
- Join tra più tabelle in dplyr
- Valutazione tidy: {{ }} e .data