Day 14 of 30·Functions & Macro-like Behavior
Conditional & Tidy Evaluation Patterns
Writing flexible functions that take column names — the tidyverse way.
Learning objectives
- 1Pass column names to functions with {{ }} (embracing).
- 2Build reusable summary functions over arbitrary variables.
- 3Understand the across() helper for multiple columns.
- 4Avoid common non-standard-evaluation pitfalls.
Key SAS® → R comparison
| Task | SAS® | R |
|---|---|---|
| Param a var name | &var macro variable | function(df, var) ... {{ var }} |
| Many columns | var x1-x10; | across(starts_with('x')) |
| Dynamic name out | &-resolved name | := with {{ }} |
Code examples
SAS®
%macro summ(ds, grp, var);
proc means data=&ds; class &grp; var &var; run;
%mend;R
summ <- function(df, grp, var) {
df |>
group_by({{ grp }}) |>
summarise(mean = mean({{ var }}, na.rm = TRUE))
}
summ(adsl, arm, age)Note: {{ var }} 'embraces' the column so you can pass bare column names just like a macro variable, but with real scoping.
Explanation
Tidy evaluation lets your own functions accept unquoted column names, mirroring the convenience of macro variables while keeping the safety of real functions. The {{ }} operator forwards a column reference from your function's arguments into dplyr verbs.
across() applies the same transformation to many columns selected by name or predicate, replacing variable-list shorthand like x1-x10 with explicit, testable selections.
Practice exercise
Write a function summarise_by(df, group_col, value_col) returning N and mean of value_col by group_col, then use across() to round every numeric column in a dataset to two decimals.