I'd like to perform multiple aggregations, using data.table
's lapply(.SD, ...)
approach, i.e. calculate several different summary statistics on several variables. But my guesses as to how to do this end in either errors or the equivalent of rbind
rather than cbind
.
For example, to get the mean and median mpg in mtcars by cyl, one could do the following:
mtcars.dt <- data.table(mtcars)
mtcars.dt[, list(mpg.mean = mean(mpg), mpg.median = median(mpg)), by = "cyl"]
# Result:
cyl mpg.mean mpg.median
|1: 6 19.74 19.7
|2: 4 26.66 26.0
|3: 8 15.10 15.2
But applying the .SD
approach either rbind
s the result on the functions:
mtcars.dt[, lapply(.SD, function(x) list(mean(x), median(x))),
by = "cyl", .SDcols = c("mpg")]
# Result:
cyl mpg
1: 6 19.7428571428571
2: 6 19.7
3: 4 26.6636363636364
4: 4 26
5: 8 15.1
6: 8 15.2
Or breaks altogether:
mtcars.dt[, lapply(.SD, list(mean, median)),
by = "cyl", .SDcols = c("mpg")]
# Result:
# Error in `[.data.table`(mtcars.dt, , lapply(.SD, list(mean, median)), :
# attempt to apply non-function
EDIT: As Senor O noted, some answers provided work for my example, but only because there's a single aggregation column. An ideal solution would work for multiple columns, for example replacing the following:
mtcars.dt[, list(mpg.mean = mean(mpg), mpg.median = median(mpg),
hp.mean = mean(hp), hp.median = median(hp)), by = "cyl"]
# Result:
cyl mpg.mean mpg.median hp.mean hp.median
1: 6 19.74 19.7 122.29 110.0
2: 4 26.66 26.0 82.64 91.0
3: 8 15.10 15.2 209.21 192.5
However, even if it works for a single column, it can still be useful. For example, my immediate use case is a function which takes a column name as a string and calculates multiple grouped-by metrics for it, something which is not possible without .SDcols
AFAIK.
See Question&Answers more detail:
os