【问题标题】:join / merge two data frames with flexible condition以灵活的条件加入/合并两个数据帧
【发布时间】:2022-01-16 21:06:56
【问题描述】:

我想我的问题可能不清楚,所以我试着澄清一下。假设我有两个要合并的数据框。两个数据框中的每一行都是唯一的公司。两个数据框还包含具有这些公司唯一标识符的特定列“id_1”和“id_2”。我希望他们使用“id_1”和“id_2”加入\合并(数据框)。 最小可重现示例 id 如下

x <- structure(list(company = c("Apple", "Amazon", "BMW", "Audi"), 
                    id_1 = c("789879978", NA_character_, "12312312", NA_character_),
                    id_2 = c("32132131", "987978987", NA_character_, NA_character_)),
               .Names = c("company", "id_1", "id_2"), row.names = c(1:4), class = "data.frame")


y <- structure(list(id_1 = c("789879978111", "987654000", "12312312", "111123231"),
                    id_2 = c("32132131", "987978987", "098099808908", "9999999991"),
                    region = c("USA", "USA", "EU", "EU")),
               .Names = c("id_1", "id_2", "region"), row.names = c(1:4), class = "data.frame")

期望的输出

structure(list(company = c("Apple", "Amazon", "BMW", "Audi"), 
               id_1 = c("789879978", NA_character_, "12312312", NA_character_),
               id_2 = c("32132131", "987978987", NA_character_, NA_character_),
               region = c("USA", "USA", "EU", NA_character_)),
        .Names = c("company", "id_1", "id_2", "region"), row.names = c(1:4), class = "data.frame")

您可能会看到“x”数据框中的 Apple“id_1”与“y”数据框中的不同,因此我需要使用“id_2”来合并这些行。亚马逊也一样,而宝马的“id_2”在两个数据帧中都是NA,所以我不能使用“id_2”,所以我需要使用“id_1”。假设由于某种原因我无法更改/修复它。所以我需要同时使用“id_1”和“id_2”来合并数据帧。问题是,如果我将两列都指定为 merge() 和/或 left_join() 中的键,它将不起作用,因为它需要两个指定列的值的完美匹配。在我的情况下,我需要使用“id_1”(如果可以匹配)或“id_2”(如果我不能使用“id_1”进行合并)的组合。

我的问题是如何使用灵活的条件合并两个数据框,即如果足以合并则使用“id_1”和/或如果我不能在“id_1”内合并则使用“id_2”

【问题讨论】:

    标签: r dplyr tidyverse


    【解决方案1】:

    你可以试试这个方法:

    
    library(tidyr)
    library(dplyr)
    
    x %>% 
      pivot_longer(-company) %>% 
      left_join(pivot_longer(y, - region)) %>% 
      pivot_wider(names_from = name, values_from = value) %>% 
      group_by(company) %>% 
      fill(!company, .direction = "downup") %>% 
      distinct()
    #> Joining, by = c("name", "value")
    #> # A tibble: 4 x 4
    #> # Groups:   company [4]
    #>   company region id_1      id_2     
    #>   <chr>   <chr>  <chr>     <chr>    
    #> 1 Apple   USA    789879978 32132131 
    #> 2 Amazon  USA    <NA>      987978987
    #> 3 BMW     EU     12312312  <NA>     
    #> 4 Audi    <NA>   <NA>      <NA>
    

    reprex package (v2.0.1) 于 2021 年 12 月 13 日创建

    【讨论】:

    • 一般情况下它会起作用,但是对于相对大的数据框可能会出现问题,因为这样的操作会增加数据框的大小
    • 你的数据框很大吗?一般来说,pivot_longer 的扩展是可以管理的,但如果是这样,那么 data.table 方法可能是另一种选择。
    【解决方案2】:
    left_join(x, y[-2], by = "id_1") %>% 
      left_join(y[-1], by = "id_2") %>% 
      mutate(region = coalesce(region.x, region.y)) %>% 
      select(-c(region.x, region.y))
    
      company      id_1      id_2 region
    1   Apple 789879978  32132131    USA
    2  Amazon      <NA> 987978987    USA
    3     BMW  12312312      <NA>     EU
    4    Audi      <NA>      <NA>   <NA>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-23
      • 2018-02-18
      • 1970-01-01
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-28
      相关资源
      最近更新 更多