dplyr是否被排斥加入?

时间:2018-10-17 18:37:01

标签: r dplyr tidyverse tidyr

使用join中的各种dplyr函数时,可以将所有具有相同名称的变量(默认情况下)联接在一起,也可以使用by = c("a" = "b")指定这些变量。有没有一种排除方式加入的方式?例如,我在两个数据框中有1000个变量,我想将它们中的999个连接起来,而忽略其中一个。我不想做by = c("a1" = "b1", ...,"a999" = "b999")。是否可以通过排除未使用的一个变量来加入?

好,使用这个示例中的一个答案:

set.seed(24)
df1 <- data_frame(alala= LETTERS[1:3], skks= letters[1:3], sskjs= 
                  letters[1:3], val = rnorm(3))
df2 <- data_frame(alala= LETTERS[1:3], skks= letters[1:3], sskjs= 
                   letters[1:3], val = rnorm(3))

我想使用val以外的所有变量来加入它们。我正在寻找更通用的解决方案。假设有1000个变量,而我只记得要在联接中排除的变量的名称,却不知道该变量的索引。仅知道要排除的变量名称时如何执行联接。我知道我可以先找到列索引,但是有没有一种简单的方法可以在by =中添加排除项?

2 个答案:

答案 0 :(得分:3)

我们创建一个命名向量来实现

library(dplyr)
grps <- setNames(paste0("b", 1:999), paste0("a", 1:999))

请注意,由于OP的帖子建议了一种模式,因此使用paste创建了“ grps”向量。如果没有模式,但是我们知道该列不会被分组

nogroupColumn <- "someColumn"
grps <- setNames(setdiff(names(df1), nogroupColumn), 
                   setdiff(names(df2), nogroupColumn))

inner_join(df1, df2, by = grps)

使用可复制的示例

set.seed(24)
df1 <- data_frame(a1 = LETTERS[1:3], a2 = letters[1:3], val = rnorm(3))
df2 <- data_frame(b1 = LETTERS[3:4], b2 = letters[3:4], valn = rnorm(2))
grps <- setNames(paste0("b", 1:2), paste0("a", 1:2))

inner_join(df1, df2, by = grps)
# A tibble: 1 x 4
#  a1    a2      val   valn
#  <chr> <chr> <dbl>  <dbl>
#1 C     c     0.420 -0.584

答案 1 :(得分:1)

要排除某些字段,您需要标识所需列的索引。这是一种方法:

which(!names(df1) %in% "sskjs" ) #<this excludes the column "sskjs"
[1] 1 2 4                        #<and shows only the desired index columns

使用unite在每个数据帧中创建一个join_id,并以此联接。

df1 <- df1 %>% 
    unite(join_id, which(!names(.) %in% "sskjs"), remove = F)

df2 <- df2 %>% 
    unite(join_id, which(!names(.) %in% "sskjs"), remove = F)

left_join(df1, df2, by = "join_id" )