我有一个像这样的data.table out
(实际上它要大得多):
out <- code weights group
1: 2 0.387 1
2: 1 0.399 1
3: 2 1.610 1
4: 3 1.323 2
5: 2 0.373 2
6: 1 0.212 2
7: 3 0.316 3
8: 2 0.569 3
9: 1 0.120 3
10: 1 0.354 3
它有3组不同的代码(第1列)。在组#1中,代码3不会出现,而在另一组中则显示。
然后,我想对每个组和代码组合的权重求和。我用这个命令实现了这个目的:
sum.dt <- out[,.(sum(weights)), by=list(code,group)][order(-V1)]
这种方法效果很好,但它没有组合1和代码3的组合,因为它不在out
表中。我希望在sum.dt
中包含所有可能的组合,如果源表中没有出现组合,则它应总计为0,这意味着列V1
在此行中应为0。 / p>
知道如何实现这个目标吗?
答案 0 :(得分:6)
使用CJ
(交叉联接),您可以添加缺少的组合:
library(data.table)
setkey(out, code, group)
out[CJ(code, group, unique = TRUE)
][, lapply(.SD, sum), by = .(code, group)
][is.na(weights), weights := 0]
给出:
code group weights 1: 1 1 0.399 2: 1 2 0.212 3: 1 3 0.474 4: 2 1 1.997 5: 2 2 0.373 6: 2 3 0.569 7: 3 1 0.000 8: 3 2 1.323 9: 3 3 0.316
或者xtabs
正如@alexis_laz在评论中所示:
xtabs(weights ~ group + code, out)
给出:
code group 1 2 3 1 0.399 1.997 0.000 2 0.212 0.373 1.323 3 0.474 0.569 0.316
如果要在长格式数据框中获取此输出,可以将xtabs
代码包装在 reshape2 的melt
函数中(或 data.table )包:
library(reshape2)
res <- melt(xtabs(weights ~ group + code, out))
给出:
> class(res) [1] "data.frame" > res group code value 1 1 1 0.399 2 2 1 0.212 3 3 1 0.474 4 1 2 1.997 5 2 2 0.373 6 3 2 0.569 7 1 3 0.000 8 2 3 1.323 9 3 3 0.316
您也可以使用 dplyr 和 tidyr 的组合来完成此操作:
library(dplyr)
library(tidyr)
out %>%
complete(code, group, fill = list(weights=0)) %>%
group_by(code, group) %>%
summarise(sum(weights))
答案 1 :(得分:1)
我遇到了类似的问题,并且CJ
由于某种原因无法正常工作。我最终使用的一个相对简单的解决方案是先调用dcast
,然后调用melt
(类似于上面的xtable
解决方案),这也可以方便地为缺失的组合指定填充值。
sum.dt <- dcast(out, code ~ group, value.var = 'weights',
fun.aggregate = sum, fill = 0)
sum.dt <- melt(sum.dt, id.vars = 'code', variable.name = 'group')
这给
> sum.dt
code group value
1: 1 1 0.399
2: 2 1 1.997
3: 3 1 0.000
4: 1 2 0.212
5: 2 2 0.373
6: 3 2 1.322
7: 1 3 0.474
8: 2 3 0.569
9: 3 3 0.316