Skip to content

Commit d08b70d

Browse files
add jj usage description as add working examples
1 parent 6aa99f5 commit d08b70d

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
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 (§6). Three new examples demonstrate proper usage, including function parameter references (e.g., sum(value > threshold)) and multi-aggregation patterns.
31+
3032
# data.table [v1.17.0](https://github.com/Rdatatable/data.table/milestone/34) (20 Feb 2025)
3133

3234
## POTENTIALLY BREAKING CHANGES

man/groupingsets.Rd

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ groupingsets(x, \dots)
3434
The \code{label} argument can be a named list of scalars, or a scalar, or \code{NULL}. When \code{label} is a list, each element name must be (1) a variable name in \code{by}, or (2) the first element of the class in the data.table \code{x} of a variable in \code{by}, or (3) one of 'character', 'integer', 'numeric', 'factor', 'Date', 'IDate'. The order of the list elements is not important. A label specified by variable name will apply only to that variable, while a label specified by first element of a class will apply to all variables in \code{by} for which the first element of the class of the variable in \code{x} matches the \code{label} element name, except for variables that have a label specified by variable name (that is, specification by variable name takes precedence over specification by class). For \code{label} elements with name in \code{by}, the class of the label value must be the same as the class of the variable in \code{x}. For \code{label} elements with name not in \code{by}, the first element of the class of the label value must be the same as the \code{label} element name. For example, \code{label = list(integer = 999, IDate = as.Date("3000-01-01"))} would produce an error because \code{class(999)[1]} is not \code{"integer"} and \code{class(as.Date("3000-01-01"))[1]} is not \code{"IDate"}. A corrected specification would be \code{label = list(integer = 999L, IDate = as.IDate("3000-01-01"))}.
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.
37+
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 created with \code{substitute()}, which captures both the expression and its 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.
3739
}
3840
\value{
3941
A data.table with various aggregates.
@@ -81,5 +83,12 @@ cube(DT, j = c(list(count=.N), lapply(.SD, sum)), by = c("color","year","status"
8183
# groupingsets
8284
groupingsets(DT, j = c(list(count=.N), lapply(.SD, sum)), by = c("color","year","status"),
8385
sets = list("color", c("year","status"), character()), id=TRUE)
86+
# Using jj argument(enables access to variables from outer environments)
87+
groupingsets(DT, jj = substitute(c(list(count=.N), lapply(.SD, sum))), by = c("color","year","status"), # Basic jj usage with substitute()
88+
sets = list("color", c("year","status"), character()), id = TRUE, .SDcols = "value")
89+
groupingsets(DT, jj = substitute(lapply(.SD, sum)), by = c("color","year","status"), # Simple aggregation with jj
90+
sets = list("color", c("year","status"), character()), id = TRUE, .SDcols = "value")
91+
groupingsets(DT, jj = substitute(list(count = .N, total = sum(value))), by = c("color","year","status"), # jj with direct column references
92+
sets = list("color", c("year","status"), character()), id = TRUE)
8493
}
8594
\keyword{ data }

0 commit comments

Comments
 (0)