7

我尝试达到与 dlply 相同的效果data.table。所以就像一个非常简单的例子:

library(plyr)
library(data.table)
dt <- data.table( p = c("A", "B"), q = 1:2 )

dlply( dt, "p", identity )
$A
  p q
1 A 1

$B
  p q
1 B 2

dt[ , identity(.SD), by = p ]
   p q
1: A 1
2: B 2

foo <- function(x) as.list(x)
dt[ , foo(.SD), by = p ]
   p q
1: A 1
2: B 2

显然 的返回值foo被折叠为 one data.table。而且我不想使用,因为它通过了dlply拆分data.tables,这使得进一步的 data.table 操作效率低下。data.framesfoofoo

4

3 回答 3

3

这是一个更有data.table针对性的方法:

setkey(dt, p)
dt[, list(list(dt[J(.BY[[1]])])), by = p]$V1
#[[1]]
#   p q
#1: A 1
#
#[[2]]
#   p q
#1: B 2

上面还有更多data.table样式替代方案,但这似乎是最快的 - 这是与以下内容的比较lapply

dt <- data.table( p = rep( LETTERS[1:25], 1E6), q = 25*1E6, key = "p" )
microbenchmark(dt[, list(list(dt[J(.BY[[1]])])), by = p]$V1, lapply(unique(dt$p), function(x) dt[x]), times = 10)
#Unit: seconds
#                                        expr      min       lq   median       uq      max neval
#dt[, list(list(dt[J(.BY[[1]])])), by = p]$V1 1.111385 1.508594 1.717357 1.966694 2.108188    10
#     lapply(unique(dt$p), function(x) dt[x]) 1.871054 1.934865 2.216192 2.282428 2.367505    10
于 2013-05-22T14:55:59.403 回答
2

尝试这个:

> split(dt, dt[["p"]])
$A
   p q
1: A 1

$B
   p q
1: B 2
于 2013-05-22T09:44:09.767 回答
2

关于 G. Grothendieck 的回答,我很好奇 split 的表现如何:

dt <- data.table( p = rep( LETTERS[1:25], 1E6), q = 25*1E6, key = "p" )

system.time(
  ll <- split(dt, dt[ ,p ] )
)
  user  system elapsed 
  5.237   1.340   6.563 

system.time(
  ll <- lapply( unique(dt[,p]), function(x) dt[x] )
)
  user  system elapsed 
  1.179   0.363   1.541

所以如果没有更好的答案,我会坚持

lapply( unique(dt[,p]), function(x) dt[x] )
于 2013-05-22T10:03:03.680 回答