我尝试实现与data.table
相同的dlply。所以就像一个非常简单的例子:
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
的返回值已折叠为一个data.table
。我不想使用dlply
,因为它将data.tables
分割为data.frames
到foo
,这使得foo
内的进一步data.table操作效率低下。
答案 0 :(得分: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
答案 1 :(得分:2)
试试这个:
> split(dt, dt[["p"]])
$A
p q
1: A 1
$B
p q
1: B 2
答案 2 :(得分:2)
关于G.格洛腾迪克的答案,我很好奇分裂的表现如何:
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] )