Соединение Dplyr по максимальному значению соответствия, если точное совпадение невозможно

Я пытаюсь объединить две таблицы в dplyr. Иногда возможно точное совпадение по году столбца, но в некоторых случаях совпадающий год недоступен. В этом случае я хотел бы присоединиться к максимальному году

Left <- tibble(id = c(1,2,3),
           year = c(2010,2010,2012))

Right <- tibble(id = c(1,1,2,3,3),
            year = c(2010,2011,2010,2010,2011),
            new = c(T,T,T,T,T))

Joined <- left_join(Left, Right, by = c("id", "year"))

# A tibble: 3 x 3
     id  year   new
  <dbl> <dbl> <lgl>
1     1  2010  TRUE
2     2  2010  TRUE
3     3  2012    NA

Как вы можете видеть, id 3 не совпадает, я пробовал пакет fuzzyjoin, но я не могу нечеткого соединения в одном столбце и точного соединения в другом:

Fuzzy_joined <- fuzzyjoin::difference_left_join(Left, Right, by = c("id", "year"))
Fuzzy_joined
# A tibble: 9 x 5
   id.x year.x  id.y year.y   new
  <dbl>  <dbl> <dbl>  <dbl> <lgl>
1     1   2010     1   2010  TRUE
2     1   2010     1   2011  TRUE
3     1   2010     2   2010  TRUE
4     2   2010     1   2010  TRUE
5     2   2010     1   2011  TRUE
6     2   2010     2   2010  TRUE
7     2   2010     3   2010  TRUE
8     2   2010     3   2011  TRUE
9     3   2012     3   2011  TRUE

Каков наиболее эффективный способ объединения несовпадающих регистров на наименьшем расстоянии от переменной года и точного соответствия переменной id с использованием синтаксиса dplyr?

1 ответ

Решение

Я бы использовал левое соединение по идентификатору и году, а затем применил фильтр, чтобы получить лучшее совпадение за год

left_join(Left, Right, by = "id", suffix  = c("", "_r")) %>% 
  mutate(delta = year - year_r) %>% 
  filter(delta >= 0) %>% 
  group_by(id, year) %>% 
  slice(which.min(delta)) %>% 
  select(-delta)

# A tibble: 3 x 4
# Groups:   id, year [3]
     id  year year_r   new
  <dbl> <dbl>  <dbl> <lgl>
1     1  2010   2010  TRUE
2     2  2010   2010  TRUE
3     3  2012   2011  TRUE

Могут быть более эффективные решения, но это будет хорошо работать с наборами данных среднего размера.

Другие вопросы по тегам