我在寻找模式操纵data.table
对象,其结构类似于与创建dataframes的melt
从reshape2
包。 我处理上百万行的数据表。 性能是至关重要的。
这个问题的一般形式是,是否有分组依据值的列的一个子集,并有分组操作的结果来执行的方式创建一个或多个新列。
这个问题的具体形式可能是如何使用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
快速未经测试的答案:好像你正在寻找的,不逐 ,又名分组按我 :
setkey(input,variable)
input[c("x","y"),sum(value)]
这就像在SQL快速拥有。 j
获取的每一行评估i
。 换句话说,上面是同样的结果,但比快得多:
input[,sum(value),keyby=variable][c("x","y")]
后者的子集和evals所有组(浪费)选择感兴趣只有组之前。 前者( 通过,而无需逐 )去直接只组的子集。
本组结果将在长格式返回,一如既往。 但是对整形后宽的(比较小)汇总的数据应该是相对瞬间。 这就是思维反正。
第一setkey(input,variable)
如果会咬input
有很多不感兴趣的列。 如果是的话,它可能是值得子集化所需的列:
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']
如果合并的副无需-通过用,如上面,然后将副无需逐然后运行就像一个子集; 即, j
仅运行的每一行i
当由缺少(故名通过,而无需逐个 )。 所以,你需要包括variable
,再次,在by
如上图所示。
或者,通过以下应组id
在“X”和“Y”代替工会(但上面是你问的问题中,IIUC):
input[c("x","y"),sum(value),by=id]
> setkey(input, "id")
> input[ , list(sum(value)), by=id]
id V1
1: 1 6
2: 2 15
3: 3 34
> input[ variable %in% c("x", "y"), list(sum(value)), by=id]
id V1
1: 1 6
2: 2 15
3: 3 24
最后一个:
> input[ variable %in% c("x", "y"), list(sum(value)), by=list(id, variable)]
id variable V1
1: 1 x 1
2: 1 y 5
3: 2 x 4
4: 2 y 11
5: 3 x 15
6: 3 y 9
我不知道这是否是最好的方式,但你可以尝试:
input[, list(x = sum(value[variable == "x"]),
y = sum(value[variable == "y"])), by = "id"]
# id x y
# 1: 1 1 5
# 2: 2 4 11
# 3: 3 15 9