Сопоставление строк двух фреймов данных на основе нескольких условий - PullRequest
0 голосов
/ 10 апреля 2020

Например, если у меня есть два фрейма данных df1 и df2, каждый из которых имеет 3 столбца с именами столбцов c («Имя», «Регион», «Состояние») и выглядит следующим образом:

df1:

Name  Region             State
A     Boston City        Mass
B     Washington D.C.    NA
C     New York           NY

df2:

Name  Region             Job
C     Boston             Massachusetts
B     D.C.               NA
A     Boston             Massachusetts
D     Dallas             Texas

Что я хочу сделать, это посмотреть, есть ли в строке в df1 соответствующая строка в df2 путем точного соответствия имени, но только частично совпадают «Регион» и «Работа». Например, «Бостон Сити» и «Бостон» должны рассматриваться как одинаковые (то же самое для «Вашингтон Д. C.» И «Д. C.»), А «Массачусетс» и «Массачусетс» должны рассматриваться одинаково. также. Таким образом, строки с именами «A» и «B» в df1 должны успешно совпадать для соответствующих строк с именами «A» и «B» в df2. То, что я хочу для результата - это фрейм данных с двумя столбцами. Столбец 1 - это индексы строк df1, у которых есть совпадение в df2, а столбец 2 - это индексы строк соответствующих совпадающих строк в df2. То есть

Column1  Column2
1        3
2        2

Я знаю, что, вероятно, могу использовать grep для частичного сопоставления? Но я до сих пор не знаю, как достичь своей цели. Спасибо!

1 Ответ

1 голос
/ 10 апреля 2020

Мы можем создать индекс строки для каждого фрейма данных, а затем full_join на основе столбца Name. Затем мы выбираем только те строки, в которых Region частично совпадает, а Job и State частично совпадают. Мы также выбираем строки, когда оба столбца имеют значения NA.

library(dplyr)
library(stringr)

df1 %>%
  mutate(Column1=row_number()) %>%
  full_join(df2 %>% mutate(Column2 = row_number()), by = 'Name') %>%
  filter((str_detect(Region.x, fixed(Region.y)) | 
                   (is.na(Region.x) & is.na(Region.y))) & 
       (str_detect(Job, fixed(State)) | (is.na(Job) & is.na(State)))) %>%
   select(Column1, Column2)

#  Column1 Column2
#1       1       3
#2       2       2

данные

df1 <-  structure(list(Name = c("A", "B", "C"), Region = c("BostonCity", 
"WashingtonD.C.", "NewYork"), State = c("Mass", NA, "NY")), row.names = c(NA, 
-3L), class = "data.frame")

df2 <- structure(list(Name = c("C", "B", "A", "D"), Region = c("Boston", 
"D.C.", "Boston", "Dallas"), Job = c("Massachusetts", NA, "Massachusetts", 
"Texas")), row.names = c(NA, -4L), class = "data.frame")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...