2014-02-12 75 views
4

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

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

我看到数据的方式被拆分成嵌套组。第一部分发生在项目层面(直线),第二部分发生在团队层面(虚线)。

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 

从我想加入到他们每个人的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 

换言之,将数据使用event作为密钥by后,我需要划分的第二时间,并比较与所述第二分束而获得的数据的块。 但这里的问题是,我不知道如何引用与by获得的第一块,然后再次如何拆分,并在数据库之间进行比较。你有什么想法我可以解决这个问题吗?

如果你能帮助我,我将非常感激。真。

回答

4

这里有一个简单的方法:

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

然后,您只需更换NA用0如下:

ans[is.na(freqrel), freqrel := 0.0] 

一些解释:你的问题归结到这一点 - 为每个event,你想要所有可能的组合id, membr,这样你就可以在这个全组合wi薄组合使用.SD

所以,首先我们按event,并在这一点,我们首先得到id, membr所有组合与CJ的帮助(这将默认密钥集所有列)。但是,要执行加入,我们需要为.SD设置密钥。因此,我们将key设置为dt预设为id, membr。因此,我们在每个组中执行连接,并为您提供预期的结果。希望这个对你有帮助。

+0

我非常感谢。我会研究你的解决方案以完全理解它。非常感谢。 – Riccardo

+0

它帮了很多。这是一个很好的解决方案,我很高兴我问了这个问题,因为你的回答让我意识到我永远不会独自一人。非常感谢。编码风格的一个很好的教训。 – Riccardo

+0

@Arun @Riccardo:我看到这已经超过了一个月的时间,但我认为这可能很重要。首先,'.SD [CJ()]'部分的工作原理只是因为'nomatch = NA'默认情况下。第二,在**'.SD'中使用**的方式,'unique()'只包含'id'的值,和'membr',在**之后发现**数据表已经按照by =而不是整个数据表中的子集。这可能是这里的预期行为(每个“事件”有不同的'membr'集合),但可能不是。 – Peter