我想使用data.tablelapply(.SD, ...)方法执行多种汇总,即针对多个变量计算几种不同的汇总统计信息。但是我对如何执行此操作的猜测以错误或等效的rbind而不是cbind结束。
例如,要通过cyl获取mtcar的平均值和中位数mpg,可以执行以下操作:

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
但是,使用.SD方法或rbind会在函数上生成结果:
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
或完全中断:
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
编辑:正如Senor O所指出的,一些答案为我的示例提供了工作,但这仅仅是因为只有一个聚合列。理想的解决方案适用于多列,例如替换以下内容:
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
但是,即使它适用于单个列,它也仍然有用。例如,我的直接用例是一个函数,该函数将列名作为字符串并为其计算多个分组度量,如果没有.SDcols AFAIK,这是不可能的。

最佳答案

您缺少[[1]]$mpg:

mtcars.dt[, lapply(.SD, function(x) list(mean(x), median(x)))[[1]],
            by="cyl", .SDcols=c("mpg")]
#or
mtcars.dt[, lapply(.SD, function(x) list(mean(x), median(x)))$mpg,
            by="cyl", .SDcols=c("mpg")]
#   cyl       V1   V2
#1:   6 19.74286 19.7
#2:   4 26.66364 26.0
#3:   8 15.10000 15.2

对于更一般的情况,请尝试:
mtcars.dt[, as.list(unlist(lapply(.SD, function(x) list(mean=mean(x),
                                                        median=median(x))))),
            by="cyl", .SDcols=c("mpg", "hp")]
#    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

(或as.list(sapply(.SD, ...)))

09-30 15:31
查看更多