R 使用lappy(.SD,…)计算多个变量的多个聚合

R 使用lappy(.SD,…)计算多个变量的多个聚合,r,data.table,R,Data.table,我想使用data.table的lapply(.SD,…)方法执行多个聚合,即计算多个变量的多个不同汇总统计数据。但我对如何做到这一点的猜测要么是错误,要么相当于rbind,而不是cbind 例如,要按cyl获取mtcars中的平均mpg和中值mpg,可以执行以下操作: mtcars.dt <- data.table(mtcars) mtcars.dt[, list(mpg.mean = mean(mpg), mpg.median = median(mpg)), by = "cyl

我想使用
data.table
lapply(.SD,…)
方法执行多个聚合,即计算多个变量的多个不同汇总统计数据。但我对如何做到这一点的猜测要么是错误,要么相当于
rbind
,而不是
cbind

例如,要按cyl获取mtcars中的平均mpg和中值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
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
或完全中断:

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 <- 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
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,这是不可能的。

在单击“询问”后立即实现:)解决方案是列出
lappy
s:

mtcars.dt[, list(mpg.mean=lapply(.SD, mean), mpg.median=lapply(.SD, median)), 
          by="cyl", .SDcols=c("mpg")]
# Solution:
    cyl mpg.mean mpg.median
|1:   6    19.74       19.7
|2:   4    26.66       26.0
|3:   8    15.10       15.2

您缺少一个
[[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,…)

-1。这是多余的,因为只有当
.SD
只有一列时,才能期望良好的行为,在这种情况下,最好在j(
lappy(mpg,函数(x)列表(平均值(x),中值(x)))中显式使用该列名称。
)感谢您注意到目前为止提供的解决方案可能会涉及我的示例,但不会涉及多栏示例;更新问题以反映这一点。不过,正如我在编辑中所指出的,如果提供一个列作为字符串聚合,则解决方案仍然很有用,例如在函数中。谢谢,我认为这几乎可以用于多个列(请参见问题编辑)。对适当的修改有什么想法吗?