data.table生成多列并汇总

data.table generate multiple columns and summarize them

我正在努力学习 data.table 语法。我掌握了简单摘要的大部分基础知识,但我不知道如何使用 data.table 从现有列生成新列并进行摘要。

这是一个 MWE 示例,我使用 dplyr 和 base 工具从一列创建多列,然后通过分组变量进行汇总:

当前输入

##    fact1 fact2 X0
## 1      b     2  9
## 2      a     2  6
## 3      b     1  7
## 4      c     2  3
## 5      a     1  8
## 6      a     1  4
## 7      a     1  5
## 8      a     1  1
## 9      b     1  2
## 10     b     2 10

Base + dlyr 代码

set.seed(10)
dat <- data.frame(
    fact1 = factor(sample(c('a', 'b', 'c'), 10, TRUE)), 
    fact2 = factor(sample(1:2, 10, TRUE)), 
    X0 = sample(1:10, 10)
)

add <- function(x, y) x + y
z <- sample(1:10, 6, FALSE)

library(dplyr)

z %>% 
    lapply(., add, dat[, 'X0']) %>%
    do.call(cbind, .) %>%
    cbind(dat, .) %>%
    data.frame() %>%
    group_by(fact1, fact2) %>%
    summarise_each(funs(sum))

期望输出

## Source: local data frame [5 x 9]
## Groups: fact1
## 
##   fact1 fact2 X0 X1 X2 X3 X4 X5 X6
## 1     a     1 18 42 22 26 46 30 34
## 2     a     2  6 12  7  8 13  9 10
## 3     b     1  9 21 11 13 23 15 17
## 4     b     2 19 31 21 23 33 25 27
## 5     c     2  3  9  4  5 10  6  7

虽然我要求 data.table 具体解决方案,但我认为看到 base 和 dplyr 等聪明的解决方案可能会使这个问题吸引更广泛的 reader。

可能有更好的方法

library(data.table)
setDT(dat)[, paste0("X", 1:6):= lapply(z, add, X0),
           ][, lapply(.SD, sum), by = .(fact1, fact2)]

#    fact1 fact2 X0 X1 X2 X3 X4 X5 X6
# 1:     b     2 19 31 21 23 33 25 27
# 2:     a     2  6 12  7  8 13  9 10
# 3:     b     1  9 21 11 13 23 15 17
# 4:     c     2  3  9  4  5 10  6  7
# 5:     a     1 18 42 22 26 46 30 34

一个base R选项是

dat[paste0('X', 1:6)] <- Map(add, list(dat$X0), z)
aggregate(.~fact1+fact2, dat, FUN=sum)
#  fact1 fact2 X0 X1 X2 X3 X4 X5 X6
#1     a     1 18 42 22 26 46 30 34
#2     b     1  9 21 11 13 23 15 17
#3     a     2  6 12  7  8 13  9 10
#4     b     2 19 31 21 23 33 25 27
#5     c     2  3  9  4  5 10  6  7

或一步到位

aggregate(.~fact1+fact2, cbind(dat, mapply(add, list(dat$X0), z)), FUN=sum)