Skip to content

Commit 57f5baf

Browse files
pass a list of param equal value in substitute
1 parent 05d166e commit 57f5baf

File tree

2 files changed

+6
-4
lines changed

2 files changed

+6
-4
lines changed

NEWS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
+ Argument `in.place` to `droplevels` has been removed.
2828
+ It's now an error to set `datatable.nomatch`, which has been warning since 1.15.0.
2929

30-
3. The groupingsets() documentation now explicitly addresses scoping issues when using variables from outer environments (e.g., function parameters) in aggregation expressions. Previously, using such variables in j could lead to "object not found" errors due to evaluation environment mismatches. This is resolved by using jj = substitute(expr) instead, which captures both the expression and its environment per R’s scoping rules (Chapter 6 of the R Language Definition manual). Three new examples demonstrate proper usage, including function parameter references (e.g., sum(value > threshold)) and multi-aggregation patterns.
30+
3. The groupingsets() documentation now explicitly addresses scoping issues when using variables from outer environments (e.g., function parameters) in aggregation expressions. Previously, using such variables in j could lead to "object not found" errors due to evaluation environment mismatches. This is resolved by using jj = substitute(expr, list(param=value)) instead, which creates an expression with values directly substituted at call time, following R's evaluation rules (Chapter 6 of the R Language Definition manual). Three new examples demonstrate proper usage, including function parameter references (e.g., sum(value > threshold)) and multi-aggregation patterns.
3131

3232
# data.table [v1.17.0](https://github.com/Rdatatable/data.table/milestone/34) (20 Feb 2025)
3333

man/groupingsets.Rd

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ groupingsets(x, \dots)
3535

3636
The \code{label = <scalar>} option provides a shorter alternative in the case where only one class of grouping variable requires a label. For example, \code{label = list(character = "Total")} can be shortened to \code{label = "Total"}. When this option is used, the label will be applied to all variables in \code{by} for which the first element of the class of the variable in \code{x} matches the first element of the class of the scalar.
3737

38-
The \code{jj} argument provides a mechanism to handle scoping issues when working with variables from outer environments. When using \code{j} directly with variables not defined in the columns of the data.table, R's evaluation rules may not find these variables, resulting in "object not found" errors. The \code{jj} argument accepts a quoted expression which can be created with either \code{quote()} (for direct calls referencing only columns and special symbols) or \code{substitute()} (when inside functions that need to capture parameters from the outer environment). This approach is particularly useful in functions where parameters need to be referenced within aggregation expressions. When \code{jj} is provided, the function will ignore any value specified in the \code{j} argument.
38+
The \code{jj} argument provides a mechanism to handle scoping issues when working with variables from outer environments. When using \code{j} directly with variables not defined in the columns of the data.table, R's evaluation rules may not find these variables, resulting in "object not found" errors. The \code{jj} argument accepts a quoted expression which can be created with either \code{quote()} (for direct calls referencing only columns and special symbols) or \code{substitute()} (when inside functions that need to capture parameters from the outer environment). For reliable behavior with function parameters, especially in nested environments, use the two-argument form \code{substitute(expr, list(param=value))} which binds values rather than symbols. This approach is particularly useful in functions where parameters need to be referenced within aggregation expressions. When \code{jj} is provided, the function will ignore any value specified in the \code{j} argument.
3939
}
4040
\value{
4141
A data.table with various aggregates.
@@ -96,9 +96,11 @@ groupingsets(DT, jj = quote(list(count = .N, total = sum(value))),
9696
sets = list("color", c("year","status"), character()), id = TRUE)
9797
9898
# Example showing when substitute() is necessary - in a wrapper function
99+
# Note: Use substitute(expr, list(param=value)) to bind values, not symbols
99100
custom_grouping <- function(DT, multiplier = 1) {
100-
# Here substitute() is needed to capture 'multiplier' from function environment
101-
groupingsets(DT, jj = substitute(list(count = .N, total = sum(value) * multiplier)),
101+
# use substitute() with environment to ensure variable are properly evaluated
102+
groupingsets(DT, jj = substitute(list(count = .N, total = sum(value) * multiplier),
103+
list(multiplier = multiplier)),
102104
by = c("color", "year", "status"),
103105
sets = list("color", c("year", "status"), character()), id = TRUE)
104106
}

0 commit comments

Comments
 (0)