【问题标题】:Conditionally join R tables based on nested membership基于嵌套成员有条件地连接 R 表
【发布时间】:2021-11-21 19:22:12
【问题描述】:

考虑这个包含 3 个县、3 个城镇以及与其相关联的一系列邮政编码的嵌套数据框示例。其中两个城镇同名 (B),但位于不同的县:

df <- tibble(
  county = c(1,1,1,2,2,2,2,3),
  town = c("A","A","A","B","B","B","B","B"),
  zip = c(12864,12865,12866,89501,89502,89503,89504,76512)) %>% 
  nest(data=c(zip))

我有另一个包含城镇名称、邮政编码和占位符值的数据框,但缺少县字段:

df2 <- tibble(
  town = c("A", "B", "B"),
  zip = c(12866, 89504, 76512),
  value = c("foo", "bar", "ski"))

我的真实数据有数百个这些重复城镇名称的实例,我需要将这两个表连接在一起,以便每个城镇根据邮政编码(不是城镇名称,它有重复)获得正确的占位符值。然而,dplyr 似乎只是to join on equality。因此,我被困住了 - 我所追求的是 inner_join(df, df2, by = c(df2$zip %in% df$data$zip)) 之类的东西,但这显然行不通。

我也知道data.table 能够handle inequality in joins,但这似乎总是与大于/小于条件有关。在数据帧之间有 3 个以上整齐匹配的行的情况下,如何成功连接这些表以返回以下输出?

  county town  data             value
   <dbl> <chr> <list>           <chr>
1      1 A     <tibble [3 x 1]> foo  
2      2 B     <tibble [4 x 1]> bar  
3      3 B     <tibble [1 x 1]> ski

【问题讨论】:

    标签: r join dplyr data.table


    【解决方案1】:

    我们可以通过map 做到这一点

    library(purrr)
    library(dplyr)
    df %>% 
        mutate(value = map_chr(data, ~ inner_join(.x, df2, by = 'zip') %>% 
              pull(value)))
    

    -输出

    # A tibble: 3 × 4
      county town  data             value
       <dbl> <chr> <list>           <chr>
    1      1 A     <tibble [3 × 1]> foo  
    2      2 B     <tibble [4 × 1]> bar  
    3      3 B     <tibble [1 × 1]> ski  
    

    或者另一个选项是regex_inner_join

    library(fuzzyjoin)
    library(stringr)
    library(dplyr)
    library(purrr)
    df %>%
        mutate(zip = map_chr(data, ~ str_c(.x$zip, collapse="|"))) %>% 
        regex_inner_join(df2 %>%
              select(-town), by = "zip") %>% 
        select(-starts_with('zip'))
    

    -输出

    # A tibble: 3 × 4
      county town  data             value
       <dbl> <chr> <list>           <chr>
    1      1 A     <tibble [3 × 1]> foo  
    2      2 B     <tibble [4 × 1]> bar  
    3      3 B     <tibble [1 × 1]> ski  
    

    【讨论】:

      【解决方案2】:

      我认为你必须“自己加入”:

      df %>% mutate(value = df2$value[
        sapply(data, function(x) match(unlist(x), df2$zip) %>% .[!is.na(.)])
        ])
      

      这适用于提供的示例,但我不清楚在一组 df$data$zip 中是否可以有多个匹配 df2$zip。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多