我正在学习dplyr,来自plyr,我想从xtabs的输出生成(每组)列(每个交互).
简短摘要:我收到了
A B
1 NA
NA 2
Run Code Online (Sandbox Code Playgroud)
当我想要的时候
A B
1 2
Run Code Online (Sandbox Code Playgroud)
xtabs数据如下所示:
> xtabs(data=data.frame(P=c(F,T,F,T,F),A=c(F,F,T,T,T)))
A
P FALSE TRUE
FALSE 1 2
TRUE 1 1
Run Code Online (Sandbox Code Playgroud)
现在do(想要数据框中的数据,如下所示:
> xtabs(data=data.frame(P=c(F,T,F,T,F),A=c(F,F,T,T,T))) %>% as.data.frame
P A Freq
1 FALSE FALSE 1
2 TRUE FALSE 1
3 FALSE TRUE 2
4 TRUE TRUE 1
Run Code Online (Sandbox Code Playgroud)
现在我想要一个单行输出,其中列是级别的交互.这是我正在寻找的:
FALSE_FALSE TRUE_TRUE FALSE_TRUE TRUE_FALSE
1 1 2 1
Run Code Online (Sandbox Code Playgroud)
但相反,我得到了
> xtabs(data=data.frame(P=c(F,T,F,T,F),A=c(F,F,T,T,T))) %>%
as.data.frame %>%
unite(S,A,P) %>%
spread(S,Freq)
FALSE_FALSE FALSE_TRUE TRUE_FALSE TRUE_TRUE
1 1 NA NA NA
2 NA 1 NA NA
3 NA NA 2 NA
4 NA NA NA 1
Run Code Online (Sandbox Code Playgroud)
我显然在这里误解了一些东西.我在这里寻找相当于reshape2的代码(使用magrittr管道来保持一致性):
> xtabs(data=data.frame(P=c(F,T,F,T,F),A=c(F,F,T,T,T))) %>%
as.data.frame %>% # can be omitted. (safely??)
melt %>%
mutate(S=interaction(P,A),value=value) %>%
dcast(NA~S)
Using P, A as id variables
NA FALSE.FALSE TRUE.FALSE FALSE.TRUE TRUE.TRUE
1 NA 1 1 2 1
Run Code Online (Sandbox Code Playgroud)
(注意这里使用了NA,因为在这个简化的例子中我没有分组变量)
更新 - 有趣的是,添加一个分组列似乎解决了这个问题 - 为什么它在没有我告诉它的情况下合成(可能来自row_name)一个分组列?
> xtabs(data=data.frame(h="foo",P=c(F,T,F,T,F),A=c(F,F,T,T,T))) %>%
as.data.frame %>%
unite(S,A,P) %>%
spread(S,Freq)
h FALSE_FALSE FALSE_TRUE TRUE_FALSE TRUE_TRUE
1 foo 1 1 2 1
Run Code Online (Sandbox Code Playgroud)
这似乎是一个部分解决方案.
这里的关键是spread不聚合数据.
因此,如果您以前还没有用过xtabs聚合,那么您将这样做:
a <- data.frame(P=c(F,T,F,T,F),A=c(F,F,T,T,T), Freq = 1) %>%
unite(S,A,P)
a
## S Freq
## 1 FALSE_FALSE 1
## 2 FALSE_TRUE 1
## 3 TRUE_FALSE 1
## 4 TRUE_TRUE 1
## 5 TRUE_FALSE 1
a %>% spread(S, Freq)
## FALSE_FALSE FALSE_TRUE TRUE_FALSE TRUE_TRUE
## 1 1 NA NA NA
## 2 NA 1 NA NA
## 3 NA NA 1 NA
## 4 NA NA NA 1
## 5 NA NA 1 NA
Run Code Online (Sandbox Code Playgroud)
任何其他方式都没有意义(没有聚合).
这是基于fill参数的帮助文件可预测的:
如果其他变量和键列的每个组合都没有值,则该值将被替换.
在您的情况下,没有任何其他变量与键列组合.如果有,那么......
b <- data.frame(P=c(F,T,F,T,F),A=c(F,F,T,T,T), Freq = 1
, h = rep(c("foo", "bar"), length.out = 5)) %>%
unite(S,A,P)
b
## S Freq h
## 1 FALSE_FALSE 1 foo
## 2 FALSE_TRUE 1 bar
## 3 TRUE_FALSE 1 foo
## 4 TRUE_TRUE 1 bar
## 5 TRUE_FALSE 1 foo
> b %>% spread(S, Freq)
## Error: Duplicate identifiers for rows (3, 5)
Run Code Online (Sandbox Code Playgroud)
...它会失败,因为它无法聚合第3行和第5行(因为它不是为了设计).
该tidyr/ dplyr办法做到这将是group_by和summarize不是xtabs,因为summarize保留了分组列,因此spread可以知道哪些意见在同一行中属于:
b %>% group_by(h, S) %>%
summarize(Freq = sum(Freq))
## Source: local data frame [4 x 3]
## Groups: h
##
## h S Freq
## 1 bar FALSE_TRUE 1
## 2 bar TRUE_TRUE 1
## 3 foo FALSE_FALSE 1
## 4 foo TRUE_FALSE 2
b %>% group_by(h, S) %>%
summarize(Freq = sum(Freq)) %>%
spread(S, Freq)
## Source: local data frame [2 x 5]
##
## h FALSE_FALSE FALSE_TRUE TRUE_FALSE TRUE_TRUE
## 1 bar NA 1 NA 1
## 2 foo 1 NA 2 NA
Run Code Online (Sandbox Code Playgroud)