如何在将data.table按多个列分组时保留输出中的列

3
我将尝试“整理”一个大型数据集,其中包含多种类型的数据合并在列中,并且某些数据在列名中。这是生物数据集中常见的情况。
我的数据表格具有重复测量值,我想将其折叠成平均值。将数据转换为整洁格式后,这些重复值变为额外的行。如果我尝试按多个列进行聚合/分组并计算重复值的平均值:
collapsed.data <- tidy.dt[, mean(expression, na.rm = T), by=list(Sequence.window,Gene.names,ratio,enrichment.type,condition)]

我得到了一个结果表,只包含在by语句中使用的列,并且后面跟着mean(expression)作为列V1。是否可能也获取所有其他(未更改的)列?
以下是一个最简示例,显示我正在尝试实现的内容:
library(data.table)
dt <- data.table(a = c("a", "a", "b", "b", "c", "a", "c", "a"), b = rnorm(8), 
                 c = c(1,1,1,1,1,2,1,2), d = rep('x', 8), e = rep('test', 8))
dt[, mean(b), by = list(a, c)]
#   a c         V1
#1: a 1 -0.7597186
#2: b 1 -0.3001626
#3: c 1 -0.6893773
#4: a 2 -0.1589146

正如您所看到的,列 de 被删除了。

请按照列表a和c进行分组,计算b的平均值,并返回d和e的前一行作为结果。代码示例:dt[,.(mean(b), head(d, 1), head(e, 1)), by=list(a,c)] - Sotos
这是因为 data.table 不知道你想获取哪些 de 的值,即对于每个 ab 的组合,de 可能有多个可能的值。您需要明确指定您想要返回哪些值。 - David Arenburg
通常我会将想要保留的列添加到“by”参数中。 - BenBarnes
1个回答

9

一种可能性是将de包含在分组中:

res <- dt[, mean(b), by = list(a, c, d, e)]
res
#   a c d    e         V1
#1: a 1 x test  0.9271986
#2: b 1 x test -0.3161799
#3: c 1 x test  1.3709635
#4: a 2 x test  0.1543337

如果你想保留所有列,除了你想聚合的那一列,你可以以更加程序化的方式来处理:

cols_to_group_by <- setdiff(colnames(dt), "b")
res <- dt[, mean(b), by = cols_to_group_by]

结果与上述相同。

这样,您已经减少了行数。如果您想保留所有行,可以添加一个额外的列:

dt[, mean_b := mean(b), by = list(a, c)]
dt
#   a          b c d    e     mean_b
#1: a  1.1127632 1 x test  0.9271986
#2: a  0.7416341 1 x test  0.9271986
#3: b  0.9040880 1 x test -0.3161799
#4: b -1.5364479 1 x test -0.3161799
#5: c  1.9846982 1 x test  1.3709635
#6: a  0.2615139 2 x test  0.1543337
#7: c  0.7572287 1 x test  1.3709635
#8: a  0.0471535 2 x test  0.1543337

在这里,dt是通过引用进行修改的,即不需要复制所有的dt,这可能会节省大量时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接