在每列上混合使用不同的操作来折叠data.table

Ari*_*man 3 r collapse data.table

我有data.table以下功能:

  • bycols 将数据分成组
  • nonvaryingcols 在每个小组中保持不变(这样从每个小组中取出第一个项目并进行通过就足够了)
  • datacols 需要对它们执行一些汇总操作(例如在组内汇总)

我很好奇什么是最有效的方法,你可以称之为混合崩溃,将上述所有三个输入作为字符向量.它不一定是绝对最快的,但是使用合理的语法足够快将是理想的.

示例数据:

require(data.table)
set.seed(1)
bycols <- c("g1","g2")
datacols <- c("dat1","dat2")
nonvaryingcols <- c("nv1","nv2")
test <- data.table(
  g1 = rep( letters, 10 ),
  g2 = rep( c(LETTERS,LETTERS), each = 5 ),
  dat1 = runif( 260 ),
  dat2 = runif( 260 ),
  nv1 = rep( seq(130), 2),
  nv2 = rep( seq(130), 2) 
)
Run Code Online (Sandbox Code Playgroud)

最终数据应如下所示:

   g1 g2      dat1      dat2 nv1 nv2
1:  a  A 0.8403809 0.6713090   1   1
2:  b  A 0.4491883 0.4607716   2   2
3:  c  A 0.6083939 1.2031960   3   3
4:  d  A 1.5510033 1.2945761   4   4
5:  e  A 1.1302971 0.8573135   5   5
6:  f  B 1.4964821 0.5133297   6   6
Run Code Online (Sandbox Code Playgroud)

我已经找到了两种不同的方法,但是其中一种方法非常灵活且不实用,而且其中一种方法非常缓慢.如果没有人能够提出更好的东西,明天会发布.

Jos*_*ien 5

与这种程序化使用一样[.data.table,一般策略是构造一个e可以在j参数中进行求值的表达式.一旦你理解了(因为我确定你这样做),它就变成了一种计算语言的游戏,以获得一个j看起来像你在命令行中编写的-slot表达式.

例如,在这里,并给出了示例中的特定值,您需要一个看起来像这样的调用:

test[, list(dat1=sum(dat1), dat2=sum(dat2), nv1=nv1[1], nv2=nv2[1]),
       by=c("g1", "g2")]
Run Code Online (Sandbox Code Playgroud)

所以你想在j-slot中评估的表达式是

list(dat1=sum(dat1), dat2=sum(dat2), nv1=nv1[1], nv2=nv2[1])
Run Code Online (Sandbox Code Playgroud)

以下函数大部分用于构造该表达式:

f <- function(dt, bycols, datacols, nvcols) {
    e <- c(sapply(datacols, function(x) call("sum", as.symbol(x))),
           sapply(nvcols, function(x) call("[", as.symbol(x), 1)))
    e<- as.call(c(as.symbol("list"), e))
    dt[,eval(e), by=bycols]
}

f(test, bycols=bycols, datacols=datacols, nvcols=nonvaryingcols)
##      g1 g2      dat1      dat2 nv1 nv2
##   1:  a  A 0.8403809 0.6713090   1   1
##   2:  b  A 0.4491883 0.4607716   2   2
##   3:  c  A 0.6083939 1.2031960   3   3
##   4:  d  A 1.5510033 1.2945761   4   4
##   5:  e  A 1.1302971 0.8573135   5   5
##  ---                                  
## 126:  v  Z 0.5627018 0.4282380 126 126
## 127:  w  Z 0.7588966 1.4429034 127 127
## 128:  x  Z 0.7060596 1.3736510 128 128
## 129:  y  Z 0.6015249 0.4488285 129 129
## 130:  z  Z 1.5304034 1.6012207 130 130
Run Code Online (Sandbox Code Playgroud)