将数据帧与常用列名相结合,但列中的值不同

时间:2016-11-15 16:57:47

标签: r dplyr

我认为我遇到了一种情况(据我所知)并没有被令人敬畏的dplyr库完全覆盖,所以我想它需要的编码比我的能力要多一些。我有以下2个数据框:

df1 =
   Col1 Col2 Col3
1    A    1    X
2    A    1    X
3    B    1    X
4    C    1    X
5    D    1    Y
6    D    1    Z

df2 =

  Col1 Col2 Col3
1    A    2    X
2    B    2    Y
3    C    2    Y
4    G    2    Z
5    H    2    X
6    I    2    Z

我只想要只有Col1的公共元素的行,这是:

out =
  Col1 Col2 Col3
1    A    1    X
2    A    1    X
3    B    1    X
4    C    1    X
5    A    2    X
6    B    2    Y
7    C    2    Y

dplyr::intersect似乎会这样做,但由于Col2Col3具有不同的值,因此它为我提供了0值的表格。非常感谢您的指导。谢谢。 P. Perez。

1 个答案:

答案 0 :(得分:1)

使用基数R你可以做到:

common <- intersect(df1$Col1, df2$Col1)

df3 <- rbind(df1, df2)
df3[df3$Col1 %in% common, ]

给出:

   Col1 Col2 Col3
1     A    1    X
2     A    1    X
3     B    1    X
4     C    1    X
11    A    2    X
21    B    2    Y
31    C    2    Y

使用dplyr

bind_rows(df1, df2) %>% 
  filter(Col1 %in% intersect(df1$Col1, df2$Col1))

将为您提供相同的输出。来自评论的@Frank的替代方案:

bind_rows(df1, df2, .id = "id") %>% 
  group_by(Col1) %>% 
  filter(n_distinct(id) == 2L)

这背后的逻辑是你将两个数据帧绑定在一起,并与.id - 参数同时包含一个id-column。然后按Col1的值进行分组,并检查每个值的唯一ID数。只有一个唯一ID的那些,不会出现在两个数据帧中。

data.table包可以应用类似的逻辑:

library(data.table)
rbindlist(list(df1, df2), idcol = 'id')[, if (uniqueN(id) == 2L) .SD, by = Col1]