使用data.table嵌套分组

Ric*_*rdo 4 r data.table

data.table下面,我有关于参与项目的团队组成的信息.该变量id告诉团队ID,而变量event给出项目编号.该变量freqrel描述了团队的组成(您可以看到freqrel在每个团队中最多加1).

structure(list(id = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 
4L, 4L, 5L, 5L, 5L), event = c("127b", "127b", "127b", "127b", 
"127b", "127b", "127b", "127b", "127b", "125t", "125t", "125t", 
"125t", "125t", "125t"), membr = c("engineer", "mathematician", 
"physicist", "mathematician", "physicist", "surgeon", "dentist", 
"mathematician", "programmer", "physicist", "sociologist", "surgeon", 
"musician", "sociologist", "surgeon"), freqrel = c(0.4, 0.4, 
0.2, 0.166666666666667, 0.5, 0.333333333333333, 0.333333333333333, 
0.5, 0.166666666666667, 0.75, 0.125, 0.125, 0.444444444444444, 
0.444444444444444, 0.111111111111111)), .Names = c("id", "event", 
"membr", "freqrel"), row.names = c(NA, -15L), class = c("data.table", 
"data.frame"), sorted = c("id", "event"), .internal.selfref = <pointer: 0x039a24a0>)
Run Code Online (Sandbox Code Playgroud)

我看到数据的方式被拆分为嵌套组.第一个分区发生在项目级别(直线),第二个分支发生在团队级别(虚线).

    id event         membr   freqrel
 1:  1  127b      engineer 0.4000000
 2:  1  127b mathematician 0.4000000
 3:  1  127b     physicist 0.2000000
--------------------------------------
 4:  2  127b mathematician 0.1666667
 5:  2  127b     physicist 0.5000000
 6:  2  127b       surgeon 0.3333333
--------------------------------------
 7:  3  127b       dentist 0.3333333
 8:  3  127b mathematician 0.5000000
 9:  3  127b    programmer 0.1666667
_____________________________________
10:  4  125t     physicist 0.7500000
11:  4  125t   sociologist 0.1250000
12:  4  125t       surgeon 0.1250000
--------------------------------------
13:  5  125t      musician 0.4444444
14:  5  125t   sociologist 0.4444444
15:  5  125t       surgeon 0.1111111
Run Code Online (Sandbox Code Playgroud)

从这个起始条件开始,我想让同一个项目中的团队完全可比,通过向他们每个人添加membr团队没有特征的类型,将他们分配为freqrel = 0.结果应该是这样的:

    id event         membr   freqrel
 1:  1  127b       dentist 0.0000000  
 2:  1  127b      engineer 0.4000000
 3:  1  127b mathematician 0.4000000
 4:  1  127b     physicist 0.2000000
 5:  1  127b    programmer 0.0000000
 6:  1  127b       surgeon 0.0000000
--------------------------------------
 7:  2  127b       dentist 0.0000000  
 8:  2  127b      engineer 0.0000000
 9:  2  127b mathematician 0.1666667
 10: 2  127b     physicist 0.5000000
 11: 2  127b    programmer 0.0000000
 12: 2  127b       surgeon 0.3333333    
--------------------------------------
 13: 3  127b       dentist 0.3333333 
 14: 3  127b      engineer 0.0000000
 15: 3  127b mathematician 0.5000000
 16: 3  127b     physicist 0.0000000
 17: 3  127b    programmer 0.1666667
 18: 3  127b       surgeon 0.0000000   
_____________________________________
 19: 4  125t      musician 0.0000000
 20: 4  125t     physicist 0.7500000
 21: 4  125t   sociologist 0.1250000
 22: 4  125t       surgeon 0.1250000
--------------------------------------
 23: 5  125t      musician 0.4444444
 24: 5  125t     physicist 0.0000000
 25: 5  125t   sociologist 0.4444444
 26: 5  125t       surgeon 0.1111111
Run Code Online (Sandbox Code Playgroud)

换句话说,将所述数据与后by使用event作为密钥,我需要划分的第二时间,并比较与所述第二分束而获得的数据的块.但问题在于我不知道如何引用获得的第一个块by,然后再如何分割并在数据库的各个部分之间进行比较.你知道我怎么能解决这个问题吗?

如果你能帮助我,我会非常感激.真.

Aru*_*run 6

这是一个简单的方法:

setkey(dt, id, membr)
ans <- dt[, .SD[CJ(unique(id), unique(membr))], by=list(event)]
Run Code Online (Sandbox Code Playgroud)

然后,您可以将NA0 替换为0,如下所示:

ans[is.na(freqrel), freqrel := 0.0]
Run Code Online (Sandbox Code Playgroud)

一些解释:您的问题归结为此 - 对于每一个event,您需要所有可能的组合,id, membr以便您可以在该分组中使用此组合执行此组合的连接.SD.

所以,首先我们分组event,并在其中,我们首先得到所有组合id, membr的帮助CJ(默认情况下将键设置为所有列).但是,要执行连接,我们需要为其设置密钥.SD.因此,我们设置keydtid, membr前期.因此,我们在每个组中执行连接,并为您提供预期的结果.希望这个对你有帮助.