我有一个数据框,其中包含数据 x 和三个不同的因素(主题、任务和正确答案)。
subj <- rep(c(1,2,3), times=4)
task <- c("A","A","A","A","A","A","B","B","B","B","B","B")
correct <- c(1,1,1,0,0,0,1,1,1,0,0,0)
x <- runif(12)
df <- data.frame(subj, task, correct, x)
我想获得这三个因素的每种可能组合的试验次数(3 个主题 * 2 个任务 * 2 个正确/不正确 = 12 个组合)。当然,这是一个不好的例子,因为我只对每种组合进行了一次尝试,但你明白了。所以我这样做:
> aggregate(x~subj+task+correct, length, data=df)
subj task correct x
1 1 A 0 1
2 2 A 0 1
3 3 A 0 1
4 1 B 0 1
5 2 B 0 1
6 3 B 0 1
7 1 A 1 1
8 2 A 1 1
9 3 A 1 1
10 1 B 1 1
11 2 B 1 1
12 3 B 1 1
但现在假设我的数据中缺少一些组合:
> newdf <- df[-2,]
使用相同的聚合函数不会显示所有可能的组合,只会显示 12 个组合中的 11 个。我希望为我缺少的组合获取长度 0(或 NA,或类似的值)。
注意:有一个类似的问题here但我认为这并不能完全解决我的问题。
最佳答案
您需要 (1) 获取分组列的笛卡尔积,(2) 将其与您的 data.frame 合并回,以及 (3) 执行聚合。在 data.table 中,看起来像
library(data.table) # version 1.9.5+
setDT(newdf, key = c("subj","task","correct"))
newdf[CJ(subj, task, correct, unique=TRUE), .N, by=.EACHI]
这给出了
subj task correct N
1: 1 A 0 1
2: 1 A 1 1
3: 1 B 0 1
4: 1 B 1 1
5: 2 A 0 1
6: 2 A 1 0 # not NA
7: 2 B 0 1
8: 2 B 1 1
9: 3 A 0 1
10: 3 A 1 1
11: 3 B 0 1
12: 3 B 1 1
setDT
修改 newdf
以便 data.table 语法可以使用。设置key
按这些列对表进行排序,并为更快的合并做好准备。
CJ
采用其参数的“叉”或“笛卡尔”积。 (expand.grid
,在 @nongkrong 的回答中看到,是基本的 R 类似物。)语法 X[Y, j, by=.EACHI]
表示:merge X
和 Y
,并且对于合并列的每个唯一组合,计算 j
。在本例中,您要查找 length
,它与行数相同;在 data.table 中,.N
是该数字的快捷方式。
对于这种特殊情况,即简单地聚合观察值,我认为 @jeremycg 的答案中的方法更有意义 - 使用专门为频率列表设计的函数。
关于R 聚合并处理缺失的组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32255213/