5

我正在使用smean.cl.normalHmisc 包中的一个函数,该函数返回一个具有 3 个值的向量:平均值以及下限和上限 CI。当我在 2 个组上使用它时data.table,我得到 2 列和 6 行。有没有办法获得两行对应于 2 个组和每个函数输出的单独列的结果,即平均值和 CI?

require(Hmisc)
require(data.table)

dt = data.table(x = rnorm(100),
                gr = rep(c('A', 'B'), each = 50))

dt[, lapply(.SD, smean.cl.normal), by = gr, .SDcols = "x"]

输出:

   gr           x
1:  A -0.07916335
2:  A -0.33656667
3:  A  0.17823998
4:  B -0.02745333
5:  B -0.32950607
6:  B  0.27459941

所需的输出:

   gr        Mean         Lower         Upper
1:  A -0.07916335   -0.33656667    0.17823998
2:  B -0.02745333   -0.32950607    0.27459941
4

1 回答 1

8

中的j参数DT[i,j,by]需要一个列表,因此请使用as.list

dt[, 
  Reduce(c, lapply(.SD, function(x) as.list(smean.cl.normal(x))))
, by = gr, .SDcols = "x"]

#    gr       Mean      Lower     Upper
# 1:  A  0.1032966 -0.1899466 0.3965398
# 2:  B -0.1437617 -0.4261330 0.1386096

c(L1, L2, L3)是列表的组合方式,Reduce(c, List_o_Lists)如果您.SDcols包含的不仅仅是x. 我想do.call(c, List_o_Lists)也应该工作。


注释

由于几个原因,这是非常低效的。打开verbose=TRUE以查看 data.table 不喜欢在以下位置获取命名列表j

j 的结果是一个命名列表。为每个组一遍又一遍地创建相同的名称是非常低效的。当 j=list(...) 时,为了提高效率,在分组完成后检测、删除并放回任何名称。例如,使用 j=transform() 可以防止加速(考虑更改为 :=)。此消息将来可能会升级为警告。

此外,您错过了mean可能用于构建结果的组优化版本和其他功能。不过,这对您的用例来说可能没什么大不了的。


当您仅将其应用于单个值列时,只需:

dt[, as.list(smean.cl.normal(x)), by = gr]

就够了。

于 2017-02-10T16:40:50.653 回答