R data.table中dlply的等效值

R data.table中dlply的等效值,r,data.table,R,Data.table,我试图实现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 <- functi

我试图实现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
库(plyr)
库(数据表)
dt试试这个:

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

$B
   p q
1: B 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

以下是一种更为面向数据的方法。表
方法:

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
有更多的
数据。表
样式替代上述样式,但这似乎是最快的-下面是与
lappy
的比较:

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

dt哦,这很简单:-)我只是想知道性能,因为split没有使用
数据表
语法和功能。但你的回答实际上给了我正确方向的暗示。非常感谢!plyr是一个单独的包,用于轻松地在不同的数据结构之间进行转换。data.table作为高效/增强的data.frame实现。这是它的唯一目的。因此,没有内部有效的方法来做到这一点。您已经展示了(lappy)一个人可以做什么。为什么要拆分data.table?这违背了使用data.table的全部目的(通过避免拷贝来提高效率)。@Roland我完全同意。也许我的例子不够清楚。实际上,我想做的是对一系列数据执行操作。表子集了一些操作,这些操作最终构造了新的
引用类
对象,我想将这些对象作为列表返回。+1用于使用
。BY
,这是我还没有学会如何使用的
.VAR
之一。我不喜欢语法,但这最能回答我的问题。我刚刚意识到
dt[,list(list(…)),by=p]
不仅是我问题的最佳答案,也是最完美的答案。结果列
V1
甚至可能包含任何类型的对象(原语、S3、S4、引用类对象等)。也就是说,我更讨厌语法:-)@Beasterfield你到底讨厌什么语法?你期望的是什么,或者为什么它没有达到你的期望呢?这并不是说它不像
dlply
那么容易使用,而是在美学上我更喜欢
dlply(dt,“id”,foo)
而不是
dt[,list(list(foo(.SD))),by=id]$V1
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