Есть ли способ объединить два кадра данных с немного разными значениями строки в столбцах в R? - PullRequest
0 голосов
/ 11 апреля 2020

Я работаю над задачей R, которая включает в себя работу с 2 отдельными фреймами данных. И мне нужно объединить их в один столбец (с географическими названиями), в котором значения иногда немного отличаются, например:

«Корунья» и «Корунья А», «Аликанте / Аликант» и «Аликанте» "," Санта-Крус-де-Тенерифе "и" 4 Санта-Крус ".

Пары озера должны быть приняты за одинаковые значения при объединении фреймов данных. Таким образом, результатом слияния будет фрейм данных:

провинция | мужчины.2018 | мужчины 2013 | area

Есть ли способ сделать это, не используя дополнительные библиотеки?

Спасибо

First data frame Second data frame

Ответы [ 2 ]

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

Я не уверен, как это сделать без каких-либо внешних пакетов, возможно, используя agrep?

Пакет fuzzyjoin был разработан именно для этой ситуации. Так почему бы не воспользоваться этим. Однако значения, которым вы хотите соответствовать, не кажутся очень похожими, даже если вы сказали: «иногда значения немного отличаются ». Таким образом, решение fuzzyjoin может не помочь вам здесь. Из следующего видно:

library(fuzzyjoin)

df1 <- data.frame(province1=c("A Coruna", "Alicante/Alacant", "Santa Cruz de Tenerife"))
df2 <- data.frame(province1=c("Coruna, A", "Alicante", "4 Santa Cruz"))

data.frame(df1, df2)
               province1  province1.1
1               A Coruna    Coruna, A
2       Alicante/Alacant     Alicante
3 Santa Cruz de Tenerife 4 Santa Cruz

Следующая попытка слияния не возвращает совпадений:

merge(df1, df2, by = "province1")
# <0 rows> (or 0-length row.names)

Теперь попробуйте нечеткое сопоставление. Расстояние по умолчанию, используемое для соединения: 2.

stringdist_inner_join(df1, df2, by = "province1")
# A tibble: 0 x 2
# ... with 2 variables: province1.x <chr>, province1.y <fct>

Это не возвращает никаких записей. Поэтому попробуйте увеличить порог расстояния. В этом небольшом примере первая запись требует max.distance из 5, чтобы считаться совпадением.

stringdist_inner_join(df1, df2, by = "province1", max_dist = 5)
# A tibble: 1 x 2
  province1.x province1.y
  <chr>       <fct>      
1 A Coruna    Coruna, A

Вам необходимо увеличить порог, чтобы получить больше совпадений. Но сделать это не удалось, потому что «A Coruna» также соответствует «Alicante»!

stringdist_inner_join(df1, df2, by = "province1", max_dist = 7)
# A tibble: 2 x 2
  province1.x province1.y
  <chr>       <fct>      
1 A Coruna    Coruna, A  
2 A Coruna    Alicante

Увеличение порога до 8 приводит к «Alicante», но оно все равно соответствует «A Coruna».

stringdist_inner_join(df1, df2, by = "province1", max_dist = 8, distance_col = "dis")
# A tibble: 3 x 3
  province1.x      province1.y   dis
  <chr>            <fct>       <dbl>
1 A Coruna         Coruna, A       5
2 A Coruna         Alicante        7
3 Alicante/Alacant Alicante        8

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

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

Я думаю, что самый простой способ - это исправить имена провинций в обоих фреймах данных: вместо этого используйте коды ISO 3166-2: ES , добавленные в новый столбец. Если вы вставите данные как вывод dput в вопрос, я могу предоставить код для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...