Other answers show how to do it, but no one bothered to explain the basic principle. The basic rule is that elements of lists returned by j
expressions form the columns of the resulting data.table
. Any j
expression that produces a list, each element of which corresponds to a desired column in the result, will work. With this in mind we can use
DT[, c(mean = lapply(.SD, mean),
median = lapply(.SD, median)),
.SDcols = c('a', 'b')]
## mean.a mean.b median.a median.b
## 1: 3 4 3 4
or
DT[, unlist(lapply(.SD,
function(x) list(mean = mean(x),
median = median(x))),
recursive = FALSE),
.SDcols = c('a', 'b')]
## a.mean a.median b.mean b.median
## 1: 3 3 4 4
depending on the desired order.
Importantly we can use any method we want to produce the desired result, provided only that we arrange the result into a list as described above. For example,
library(matrixStats)
DT[, c(mean = as.list(colMeans(.SD)),
median = setNames(as.list(colMedians(as.matrix(.SD))), names(.SD))),
.SDcols = c('a', 'b')]
## mean.a mean.b median.a median.b
## 1: 3 4 3 4
also works.