双向连接在dplyr中以恢复值

时间:2015-06-12 16:21:47

标签: r left-join dplyr

我已经检查了这个问题,但找不到匹配的条目。

假设您有2个DF:

df1:mode   df2:sex
1           1
2           2
3

DF3,其中大多数组合不存在,例如

mode | sex  | cases      
1        1      9
1        1      2
2        2      7
3        1      2
1        2      5

并且你想用dplyr来总结它,获得所有组合(不存在的组合= 0):

  mode | sex  | cases      
    1        1     11
    1        2     5
    2        1     0
    2        2     7
    3        1     2
    3        2     0    

如果您执行单个left_join(left_join(df1,df3),则恢复不在df3中的模式,但“Sex”显示为“NA”,如果执行left_join(df2,df3)则相同。

那么你怎么能做左联接来恢复所有缺席组合,case = 0? dplyr首选,但sqldf是一个选项。

提前致谢,p。

2 个答案:

答案 0 :(得分:5)

tidyr 的开发版本,tidyr_0.2.0.9000,有一个名为complete的新功能,我前几天看到这个功能似乎是针对这种情况而制作的

帮助页面显示:

  

这是expand(),left_join()和replace_na的包装   用于完成缺失的数据组合。事实证明   隐式地将值缺失为明确缺失的值。

要添加df3的缺失组合并填充0值,您可以执行以下操作:

library(tidyr)
library(dplyr)

df3 %>% complete(mode, sex, fill = list(cases = 0))

  mode sex cases
1    1   1     9
2    1   1     2
3    1   2     5
4    2   1     0
5    2   2     7
6    3   1     2
7    3   2     0

您仍然需要group_bysummarise才能获得所需的最终输出。

df3 %>% complete(mode, sex, fill = list(cases = 0)) %>%
    group_by(mode, sex) %>%
    summarise(cases = sum(cases))

Source: local data frame [6 x 3]
Groups: mode

  mode sex cases
1    1   1    11
2    1   2     5
3    2   1     0
4    2   2     7
5    3   1     2
6    3   2     0

答案 1 :(得分:3)

首先,您可以使用更友好,可重复的格式获取数据

df1 <- data.frame(mode=1:3)
df2 <- data.frame(sex=1:2)
df3 <- data.frame(mode=c(1,1,2,3,1), sex=c(1,1,2,1,2), cases=c(9,2,7,2,5))

我在dplyr中没有看到完整外部联接的选项,因此我将在此处使用基本R将df1df2合并到获得所有模式/性别组合。然后我将其连接到数据并用零替换NA值。

mm <- merge(df1,df2) %>% left_join(df3)
mm$cases[is.na(mm$cases)] <- 0
mm %>% group_by(mode,sex) %>% summarize(cases=sum(cases))

给出了

  mode sex cases
1    1   1    11
2    1   2     5
3    2   1     0
4    2   2     7
5    3   1     2
6    3   2     0