【问题标题】:Replacing multiple columns from different dataframe using dplyr使用 dplyr 替换来自不同数据帧的多列
【发布时间】:2021-05-10 15:15:18
【问题描述】:

我有两个数据框,其中一个包含 ID 的子集和另一个的列(但具有不同的值)。

ds1 <- data.frame(id = c(1:4),
                      d1 = "A",
                      d2 = "B",
                      d3 = "C")


ds2 <- data.frame(id = c(1,2),
                     d1 = "W",
                     d2 = "X")

我希望在 d1 上使用 dplyr 来查找共享列,并将它们的值替换为在 d2 中找到的值,匹配 ID。我可以像这样一次改变一个:

ds1 %>% 
  mutate(d1 = ifelse(id %in% ds2$id, ds2$d1[ds2$id==id],d1),
         d2 = ifelse(id %in% ds2$id, ds2$d2[ds2$id==id],d2))

然而,在我的实际情况下,我需要这样做 47 次。有了across()的健壮性,我觉得还有更好的办法。我也对非 dplyr 解决方案持开放态度。

【问题讨论】:

    标签: r dplyr tidyr across


    【解决方案1】:

    您可能需要使用dplyrstringr(也可以不使用stringr

    
    library(tidyverse)
    
    ds1 %>% left_join(ds2, by = 'id') %>%
      mutate(across(ends_with('.y'), ~ coalesce(., get(str_replace(cur_column(), '.y', '.x'))))) %>%
      select(!ends_with('.x')) %>%
      rename_with(~str_remove(., '.y'), ends_with('.y'))
    
    #>   id d3 d1 d2
    #> 1  1  C  W  X
    #> 2  2  C  W  X
    #> 3  3  C  A  B
    #> 4  4  C  A  B
    

    reprex package (v2.0.0) 于 2021-05-10 创建

    【讨论】:

      【解决方案2】:

      使用 rows_update

      library(tidyverse)
      ds1 <- data.frame(id = c(1:4),
                        d1 = "A",
                        d2 = "B",
                        d3 = "C")
      
      
      ds2 <- data.frame(id = c(1,2),
                        d1 = "W",
                        d2 = "X")
      
      rows_update(x = ds1, y = ds2, by = "id")
      #>   id d1 d2 d3
      #> 1  1  W  X  C
      #> 2  2  W  X  C
      #> 3  3  A  B  C
      #> 4  4  A  B  C
      

      reprex package (v2.0.0) 于 2021-05-11 创建

      【讨论】:

        【解决方案3】:

        这与我的朋友亲爱的@AnilGoyal 发布的有点相似,与您的相比也有点冗长,您可以将它用于更大的数据集:

        library(dplyr)
        library(stringr)
        
        
        ds1 %>%
          left_join(ds2, by = "id") %>% 
          mutate(across(ends_with(".x"), ~ ifelse(!is.na(get(str_replace(cur_column(), ".x", ".y"))), 
                                                  get(str_replace(cur_column(), ".x", ".y")), 
                                                  .x))) %>%
          select(!ends_with(".y")) %>%
          rename_with(~ str_remove(., ".x"), ends_with(".x"))
        
        
          id d1 d2 d3
        1  1  W  X  C
        2  2  W  X  C
        3  3  A  B  C
        4  4  A  B  C
        

        【讨论】:

          猜你喜欢
          • 2016-09-17
          • 1970-01-01
          • 1970-01-01
          • 2020-01-24
          • 2015-10-23
          • 1970-01-01
          • 1970-01-01
          • 2019-09-07
          相关资源
          最近更新 更多