【问题标题】:How to remove duplicate columns after dplyr join?dplyr 加入后如何删除重复的列?
【发布时间】:2020-08-20 23:40:05
【问题描述】:

考虑两个数据框,df1df2
df1 有列 idab
df2 有列 idac

我想执行左连接,这样组合的数据框有列 idabc em>。

combined <- df1 %>% left_join(df2, by="id")

但在组合数据框中,列是 idaxbayc.

我可以在连接键中包含“a”(即:left_join(df1, df2, by=c("id", "a"))),但是像 a 这样的列太多了。我只想通过主键 id 加入并删除 df2 中的所有重复列。

【问题讨论】:

    标签: r join dplyr


    【解决方案1】:

    我喜欢用尽可能少的步骤做事。我认为这会减少步骤数:

    combine<-df1%>%
      left_join(df2, by="id", suffix=c("",".y")%>%
      select(-ends_with(".y"))
    

    选择命令中的减号表示您要选择除这些变量之外的所有内容。如果您想删除所有重复的列(根本没有 a 列),您可以这样做:

    combine<-df1%>%
      left_join(df2, by="id", suffix=c(".x",".y")%>%
      select(-ends_with(".x"),-ends_with(".y"))
    

    【讨论】:

      【解决方案2】:

      我认为这是实现您想要做的最简单的方法

      df <- left_join(df1, df2, by = "id", suffix = c("", ".annoying_duplicate_column")) %>%
        select(-ends_with(".annoying_duplicate_column"))
      

      (结合@Ernest Han 的回答和上面@David T 的非常有帮助的评论)

      【讨论】:

        【解决方案3】:

        更通用的方法是在左连接之前删除列,否则您的组合数据集最初可能会非常大:

        df1<- data.frame(id= seq(1:0), a=rnorm(1:10,0.2),b=rpois(10,0.2))
        df2<- data.frame(id= seq(1:0), a=rnorm(1:10,0.2),c=rnorm(10,0.2))
        
        varList<- names(df2)[!(names(df2) %in% names(df1))] # get non common names
        varList<- c(varList,"id") # appending key parameter
        
        combined <- df1 %>% left_join((df2 %>% select(varList)), by="id")
        

        组合数据集不会有任何 .x 或 .y

        【讨论】:

        【解决方案4】:

        “有太多像 a”这样的列你的意思是你想找到所有的列都对两个来源都通用吗?在这种情况下,为什么不直接使用交集(默认行为)?

        ## two data.frames, only id = 3, a = 4 matches
        (df1 <- data.frame(id = 1:3, a = 2:4, b = 3:5))
        #>   id a b
        #> 1  1 2 3
        #> 2  2 3 4
        #> 3  3 4 5
        (df2 <- data.frame(id = 3:2, a = 4:5, c = 1:2))
        #>   id a c
        #> 1  3 4 1
        #> 2  2 5 2
        
        ## this produces a.x and a.y                  
        dplyr::left_join(df1, df2, by = "id")
        #>   id a.x b a.y  c
        #> 1  1   2 3  NA NA
        #> 2  2   3 4   5  2
        #> 3  3   4 5   4  1
        
        ## which columns are common?
        intersect(names(df1), names(df2))
        #> [1] "id" "a"
        
        ## this produces id, a, b, c
        dplyr::left_join(df1, df2, by = intersect(names(df1), names(df2)))
        #>   id a b  c
        #> 1  1 2 3 NA
        #> 2  2 3 4 NA
        #> 3  3 4 5  1
        
        ## this is, however, the default behaviour for left_join
        ## i.e. use all columns which are present in both
        dplyr::left_join(df1, df2)
        #> Joining, by = c("id", "a")
        #>   id a b  c
        #> 1  1 2 3 NA
        #> 2  2 3 4 NA
        #> 3  3 4 5  1
        

        reprex package (v0.3.0) 于 2020 年 5 月 6 日创建

        【讨论】:

        • 发帖者不想在公共变量级别添加,他只想将“id”作为左连接的键。
        【解决方案5】:

        首先我们通过 id

        执行连接
        combined <- df1 %>% left_join(df2, by="id")
        

        然后我们用 .x 重命名并删除 .y

        combined <- combined %>% 
          rename_at(
            vars(ends_with(".x")),
            ~str_replace(., "\\..$","")
          ) %>% 
          select_at(
            vars(-ends_with(".y"))
          )
        

        【讨论】:

        • 您可以使用left_join(df2, by = "id", suffix = c("", ".y")跳过重命名 .x 变量
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        • 2017-08-16
        • 1970-01-01
        • 2015-11-08
        • 2022-01-06
        • 2018-04-07
        相关资源
        最近更新 更多