基于嵌套成员资格有条件地加入 R 表
Conditionally join R tables based on nested membership
考虑这个示例嵌套数据框,其中包含 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
似乎只是。因此,我被卡住了 - 我所追求的是 inner_join(df, df2, by = c(df2$zip %in% df$data$zip))
之类的东西,但这显然行不通。
我也知道 data.table
能够 ,但这似乎总是与比条件句更大的 than/less 相关。在数据帧之间有超过 3 个整齐匹配的行的情况下,我如何才能成功地将这些表连接到 return 以下输出?
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
我认为您必须“自行加入”:
df %>% mutate(value = df2$value[
sapply(data, function(x) match(unlist(x), df2$zip) %>% .[!is.na(.)])
])
这适用于所提供的示例,但我不清楚在一组 df$data$zip 中是否有多个 df2$zip 的匹配项。
我们可以用 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
考虑这个示例嵌套数据框,其中包含 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
似乎只是inner_join(df, df2, by = c(df2$zip %in% df$data$zip))
之类的东西,但这显然行不通。
我也知道 data.table
能够
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
我认为您必须“自行加入”:
df %>% mutate(value = df2$value[
sapply(data, function(x) match(unlist(x), df2$zip) %>% .[!is.na(.)])
])
这适用于所提供的示例,但我不清楚在一组 df$data$zip 中是否有多个 df2$zip 的匹配项。
我们可以用 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