首页 文章

如何合并两个数据帧并将具有相同名称的列替换为R中的其他列

提问于
浏览
0

我在R中有两个数据帧

df1
key      volume     name      hours      location
ABC       456       SS32      34.34       London
ERT       34        SS31      33.14       London
TYU       21        SS33      3           London
GHU       678       SS35      1.30        London
THU       67        SS35      0.30        London

df2
key      volume     hours      
ABC       345       37.34       
ERT       54        31.14       
TYU       12        6.23           
GHU       679       0.50

现在我想合并这两个数据帧,将 df1 中的列 volume and hours 替换为 df2 中的列,并且 key 列上没有匹配项,保留原始数据 df1

我想要的数据帧是

df1
key      volume     name      hours      location
ABC       345       SS32      37.34       London
ERT       54        SS31      31.14       London
TYU       12        SS33      6.23        London
GHU       679       SS35      0.50        London
THU       67        SS35      0.30        London

当我进行左连接时,它会创建一个 volume.1hours.1 作为两个新变量

2 回答

  • 0

    我认为有两种方法可以解决这个问题:

    Join then overwrite
    我可以通过加入然后使用 df2 中的值覆盖 df1 来获得结果 . 但是这个解决方案感觉非常笨重 .

    library(dplyr)
    left_join(df1, df2, by = "key", suffix = c("", ".2")) %>%
      mutate(volume = if_else(is.na(volume.2), volume, volume.2),
             hours = if_else(is.na(hours.2), hours, hours.2)) %>%
      select(-volume.2, -hours.2)
    
    #>   key volume name hours location
    #> 1 ABC    345 SS32 37.34   London
    #> 2 ERT     54 SS31 31.14   London
    #> 3 TYU     12 SS33  6.23   London
    #> 4 GHU    679 SS35  0.50   London
    #> 5 THU     67 SS35  0.30   London
    

    Bind rows
    另一种方法可能是 bind_rows 而是保留 first 值来自 df1 的名称和位置以及 last 值的体积和小时数将等于来自 df2 (如果可用)的值 . 对我而言,这比加入和覆盖更令我感到高兴 .

    bind_rows(df1, df2) %>% 
      group_by(key) %>% 
      summarise(name     = first(name),                                         
                location = first(location),
                volume   = last(volume),
                hours    = last(hours))
    #> # A tibble: 5 x 5
    #>     key  name location volume hours
    #>   <chr> <chr>    <chr>  <int> <dbl>
    #> 1   ABC  SS32   London    345 37.34
    #> 2   ERT  SS31   London     54 31.14
    #> 3   GHU  SS35   London    679  0.50
    #> 4   THU  SS35   London     67  0.30
    #> 5   TYU  SS33   London     12  6.23
    
  • 1

    这是一个解决方案:

    df3 <- inner_join(df1[c("key", "name", "location")], df2, by = "key") %>%
           bind_rows(anti_join(df1, df2, by = "key") ) %>% 
           select(key, volume, name, hours, location)
    

相关问题