运维开发网

快速融化的data.table操作

运维开发网 https://www.qedev.com 2020-04-26 15:37 出处:网络 作者:运维开发网整理
我正在寻找用于操作data.table对象的模式,其结构类似于使用reshape2包中的melt创建的数据帧.我正在处理数百万行的数据表.绩效至关重要. 问题的一般形式是,是否存在基于列中的值的子集执行分组并且使分组操作的结果创建一个或多个新列的方法. 问题的一个特定形式可能是如何使用data.table来完成dcast在以下内容中的相同操作: input <- data.table( id=
我正在寻找用于操作data.table对象的模式,其结构类似于使用reshape2包中的melt创建的数据帧.我正在处理数百万行的数据表.绩效至关重要.

问题的一般形式是,是否存在基于列中的值的子集执行分组并且使分组操作的结果创建一个或多个新列的方法.

问题的一个特定形式可能是如何使用data.table来完成dcast在以下内容中的相同操作:

input <- data.table(
  id=c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3), 
  variable=c('x', 'y', 'y', 'x', 'y', 'y', 'x', 'x', 'y', 'other'),
  value=c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
dcast(input, 
  id ~ variable, sum, 
  subset=.(variable %in% c('x', 'y')))

其输出是

id  x  y
1  1  1  5
2  2  4 11
3  3 15  9
快速未经测试的答案:看起来你正在寻找by-without-by,a.k.a.grouping-by-i:

setkey(input,variable)
input[c("x","y"),sum(value)]

这就像SQL中的快速HAVING. j得到i的每一行的评估.换句话说,以上是相同的结果,但比以下快得多:

input[,sum(value),keyby=variable][c("x","y")]

后者在选择感兴趣的组之前(浪费地)对所有组进行子集和描述.前者(by-without-by)仅直接进入组的子集.

组结果将一如既往地以长格式返回.但是,在(相对较小的)聚合数据之后重新变宽,应该是相对即时的.无论如何,这就是想法.

如果输入有很多不感兴趣的列,则第一个setkey(输入,变量)可能会咬人.如果是这样,可能需要对所需的列进行子集化:

DT = setkey(input[,c("variable","value"),with=FALSE], variable)
DT[c("x","y"),sum(value)]

将来实施二级密钥会更容易:

set2key(input,variable)              # add a secondary key 
input[c("x","y"),sum(value),key=2]   # syntax speculative

按ID分组:

setkey(input,variable)
input[c("x","y"),sum(value),by='variable,id']

并且在密钥中包含id可能值得setkey的成本取决于您的数据:

setkey(input,variable,id)
input[c("x","y"),sum(value),by='variable,id']

如果你将by-by-by与by组合在一起,那么by-without-by就像子集一样运行;即,仅当缺少by时,j仅针对i的每一行运行(因此名称by-without-by).因此,您需要再次包含变量,如上所示.

或者,以下内容应按ID分组,而不是“x”和“y”的并集(但上面是您在问题中要求的,iiuc):

input[c("x","y"),sum(value),by=id]
0

精彩评论

暂无评论...
验证码 换一张
取 消