2016-03-23 38 views
0

所有现有的组合我有一个data.table out这样的(实际上它是大得多):data.table:萨姆通过在表

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。

任何想法,我怎么能实现这一点?

+0

'setkey的(出,代码组)'; 'CJ(code,group,unique = TRUE)] [,lapply(.SD,sum),by =。(code,group)] [order(group,-weights)]' – Jaap

+0

已将此作为答复 – Jaap

+0

你也可以根据你想要做什么找到有用的数组结构。 'xtabs(权重〜组+代码,出)' –

回答

4

使用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 

如果你想在一个长格式数据帧此输出,您可以在reshape2(或data.table)封装的melt功能包裹xtabs代码:

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))