我有一个数据框,包含我的数据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,但我认为它并没有完全回答我的问题。
答案 0 :(得分:7)
您需要(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的答案中的方法更有意义 - 使用专为频率制表设计的功能。
答案 1 :(得分:6)
您可以使用基地的xtabs
:
as.data.frame(xtabs(~ subj + task + correct, data = newdf))
subj task correct Freq
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 0
9 3 A 1 1
10 1 B 1 1
11 2 B 1 1
12 3 B 1 1
更简单,再次来自@Frank:
as.data.frame(table(newdf[1:3]))
答案 2 :(得分:2)
sqldf
package的一个小技巧:
library(sqldf)
newdf <- df[-2,]
combinations <- sqldf('select *
from (select distinct subj from newdf) as a,
(select distinct task from newdf) as b,
(select distinct correct from newdf) as c')
sqldf('select c.*, count(d.x) as count_x
from combinations as c
left join newdf as d on c.subj=d.subj
and c.task=d.task
and c.correct=d.correct
group by c.subj, c.task, c.correct')
## subj task correct count_x
## 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
## 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
sqldf
包允许您使用SQL查询操作数据框,就像它们是数据库表一样。
<强>加成强>
如果您想使用此数据创建“数据透视表”,并使用正确的(1)和错误的(1)作为数据标签,则可以使用reshape
包:
aggregate_df <- sqldf('select c.*, count(d.x) as count_x
from combinations as c
left join newdf as d on c.subj=d.subj
and c.task=d.task
and c.correct=d.correct
group by c.subj, c.task, c.correct')
library(reshape)
md <- melt(aggregate_df, id=c('subj','task','correct'))
cast(md, subj+task~correct)
## subj task 0 1
## 1 1 A 1 1
## 2 1 B 1 1
## 3 2 A 1 0
## 4 2 B 1 1
## 5 3 A 1 1
## 6 3 B 1 1