【问题标题】:Joining 3 dataframes, in which duplicate entries can be present加入 3 个数据帧,其中可能存在重复条目
【发布时间】:2021-01-05 02:40:16
【问题描述】:

我有一个像这样的数据框...

df = tibble(id = c(64512, 64513, 64514, 64515), 
            customer=c("a", "a", "b", "b"))

并希望通过id 像这些一样加入另外两个数据帧...

uvp_new = tibble(id=c(64512, 64513, 64514), uvp=c(12, 14, 16))

uvp_old = tibble(id=c(64512, 64515), uvp=c(10, 18))

使用以下逻辑:每当uvp_new 中有uvp 的条目时,我想取这个(忽略uvp_old),如果uvp_new 中没有uvp 的条目,我想从uvp_old 获取uvp 的条目。

任何帮助表示赞赏

【问题讨论】:

    标签: r dplyr merge


    【解决方案1】:

    你可以left_join()uvp_old然后使用rows_update()uvp_new

    library(dplyr)
    
    df %>%
      left_join(uvp_old, by = "id") %>%
      rows_update(uvp_new, by = "id")
    
    # A tibble: 4 x 3
         id customer   uvp
      <dbl> <chr>    <dbl>
    1 64512 a           12
    2 64513 a           14
    3 64514 b           16
    4 64515 b           18
    

    或者如果df中有重复的id,先使用rows_upsert()并将结果加入df可能会更安全:

    uvp_old %>%
      rows_upsert(uvp_new, by = "id") %>%
      right_join(df, by = "id")
    

    【讨论】:

      【解决方案2】:

      这是使用transform + merge 的基本 R 选项

      transform(
        merge(merge(df, uvp_new, by = "id", all.x = TRUE), uvp_old, by = "id", all.x = TRUE),
        uvp = ifelse(is.na(uvp.x), uvp.y, uvp.x)
      )[c("id","customer","uvp")]
      

      给了

           id customer uvp
      1 64512        a  12
      2 64513        a  14
      3 64514        b  16
      4 64515        b  18
      

      【讨论】:

        【解决方案3】:

        您可以使用两个连接将这三个连接在一起,跟踪uvp 列来自哪个data.frame 和suffixes。然后,您可以使用coalesce 选择第一个非NA。

        df %>% 
          left_join(uvp_new, by = "id") %>% 
          left_join(uvp_old, by = "id", suffix = c("_new", "_old")) %>% 
          mutate(uvp = coalesce(uvp_new, uvp_old))
        
        #      id customer uvp_new uvp_old   uvp
        #   <dbl> <chr>      <dbl>   <dbl> <dbl>
        # 1 64512 a             12      10    12
        # 2 64513 a             14      NA    14
        # 3 64514 b             16      NA    16
        # 4 64515 b             NA      18    18
        

        【讨论】:

          【解决方案4】:

          您可以在 uvp_newuvp_old 之间进行完全连接,以将所有 id 放在一个数据框中,然后将这个组合的数据框与 df 连接起来,并选择新的 uvp 值(如果存在)或使用 @ 的旧值987654324@.

          library(dplyr)
          
          uvp_new %>%
            rename(uvp_n = uvp) %>%
            full_join(uvp_old %>%
            rename(uvp_o = uvp), by = 'id') %>%
            right_join(df, by = 'id') %>%
            mutate(uvp = coalesce(uvp_n, uvp_o))
          
          #     id uvp_n uvp_o customer   uvp
          #  <dbl> <dbl> <dbl> <chr>    <dbl>
          #1 64512    12    10 a           12
          #2 64513    14    NA a           14
          #3 64514    16    NA b           16
          #4 64515    NA    18 b           18
          

          如果不需要,您可以删除 uvp_nuvp_o 列。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-07-21
            • 2021-11-20
            • 1970-01-01
            • 2022-07-21
            • 2018-06-29
            • 2020-03-27
            • 1970-01-01
            • 2021-10-27
            相关资源
            最近更新 更多