Нечеткие строки объединения в нескольких столбцах в одном наборе данных - PullRequest
0 голосов
/ 09 октября 2019

Я хочу, чтобы нечеткое совпадение одного столбца (бренды df2 $) со многими другими столбцами (df1 $ F6_1: f6_12), содержащих те же строки, с некоторыми небольшими орфографическими ошибками.

У меня есть два набора данных:

df1:

df1 <- structure(list(F6_1 = c("Braand1", "Brand2", "Brand3", "Brand4", "Brand4", 
"Brand5", "Brand6", "Brand7", "Brand6", "Brand8"), F6_2 = c("Brand9", 
"", "Brand4", "Brando6", "Brand6", "Brand8", "Brannd4", "Brandd8", 
"Brand6", "Brand6"), F6_3 = c("Brand6", "", "Brand6", 
"Brand10", "Brand10", "", "Brand8", "Brand10", "Brand8", "Brand3"
), F6_4 = c("", "", "Brand10", "", "Brand3", "", "Brand6", "Brand6", 
"Bramd3", "BPand3"), F6_5 = c("", "", "", "", "Brand6", 
"", "Brand1", "Brand1", "", "Brand1"), F6_6 = c("", 
"", "", "", "Brand6", "", "Brand3", "", "", "Brand1"), F6_7 = c("", 
"", "", "", "Brand1", "", "Brand1", "", "", "Brand1"), F6_8 = c("", 
"", "", "", "Brand1", "", "", "", "", "Brand6"
), F6_9 = c("", "", "", "", "Brrandu3", "", "", "", "", ""), F6_10 = c("", 
"", "", "", "Brand6", "", "", "", "", ""), F6_11 = c("", 
"", "", "", "Brand6", "", "", "", "", ""), F6_12 = c("", "", 
"", "", "Brand6", "", "", "", "", "")), row.names = c(NA, -10L), class = c("tbl_df", 
"tbl", "data.frame"))

df2:

df2 <- structure(list(brands = c("Brand1", "Brand2", "Brand3", "Brand4", "Brand5", 
"Brand6")), row.names = c(NA, -6L), class = c("tbl_df", "tbl", 
"data.frame"))

Я попытался использовать функцию stringdist_left_join () из библиотеки fuzzyjoin, которая прекрасно работает.

library(tidyverse)
library(fuzzyjoin)

df1_F6_1 <- df1 %>% select(F6_1)
df2_F6_1 <- df2 %>% select(F6_1 = brands)

df_joined_F6_1 <- stringdist_left_join(df_F6_1, df2_F6_1, by = "F6_1", method = "soundex")

Это работает только для одного столбца. Однако я хочу сделать это в полном наборе данных df1. Эту проблему можно решить путем нечеткого соединения каждого столбца и, наконец, сложения их всех вместе. Но должен быть более простой и удобный способ сделать это.

Мой вывод должен выглядеть так:

df3 <- structure(list(F6_1 = c("Braand1", "Brand2", "Brand3", "Brand4", 
"Brand4", "Brand5", "Brand6", "Brand7", "Brand6", "Brand8"), 
    F6_1_a = c("Brand1", "Brand2", "Brand3", "Brand4", "Brand4", 
    "Brand5", "Brand6", "Brand7", "Brand6", "Brand8"), F6_2 = c("Brand9", 
    NA, "Brand4", "Brando6", "Brand6", "Brand8", "Brannd4", "Brandd8", 
    "Brand6", "Brand6"), F6_2_a = c("Brand9", NA, "Brand4", "Brand6", 
    "Brand6", "Brand8", "Brand4", "Brand8", "Brand6", "Brand6"
    ), F6_3 = c("Brand6", NA, "Brand6", "Brand10", "Brand10", 
    "Brand8", "Brand8", "Brand10", "Brand8", "Brand3"), F6_3_a = c("Brand6", 
    NA, "Brand6", "Brand10", "Brand10", "Brand8", "Brand8", "Brand10", 
    "Brand8", "Brand3"), F6_4 = c(NA, NA, "Brand10", NA, "Brand3", 
    NA, "Brand6", "Brand6", "Bramd3", "BPand3"), F6_4_a = c(NA, 
    NA, "Brand10", NA, "Brand3", NA, "Brand6", "Brand6", "Brand3", 
    "Brand3"), F6_5 = c(NA, NA, NA, NA, "Brand6", NA, "Brand1", 
    "Brand1", NA, "Brand1"), F6_5_a = c(NA, NA, NA, NA, "Brand6", 
    NA, "Brand1", "Brand1", NA, "Brand1"), F6_6 = c(NA, NA, NA, 
    NA, "Brand6", NA, "Brand3", NA, NA, "Brand1"), F6_6_a = c(NA, 
    NA, NA, NA, "Brand6", NA, "Brand3", NA, NA, "Brand1"), F6_7 = c(NA, 
    NA, NA, NA, "Brand1", NA, "Brand1", NA, NA, "Brand1"), F6_7_a = c(NA, 
    NA, NA, NA, "Brand1", NA, "Brand1", NA, NA, "Brand1"), F6_8 = c(NA, 
    NA, NA, NA, "Brand1", NA, NA, NA, NA, "Brand6"), F6_8_a = c(NA, 
    NA, NA, NA, "Brand1", NA, NA, NA, NA, NA), F6_9 = c(NA, NA, 
    NA, NA, "Brrandu3", NA, NA, NA, NA, NA), F6_9_a = c(NA, NA, 
    NA, NA, "Brand3", NA, NA, NA, NA, NA), F6_10 = c(NA, NA, 
    NA, NA, "Brand6", NA, NA, NA, NA, NA), F6_10_a = c(NA, NA, 
    NA, NA, "Brand6", NA, NA, NA, NA, NA), F6_11 = c(NA, NA, 
    NA, NA, "Brand6", NA, NA, NA, NA, NA), F6_11_a = c(NA, NA, 
    NA, NA, "Brand6", NA, NA, NA, NA, NA), F6_12 = c(NA, NA, 
    NA, NA, "Brand6", NA, NA, NA, NA, NA), F6_12_a = c(NA, NA, 
    NA, NA, "Brand6", NA, NA, NA, NA, NA)), row.names = c(NA, 
-10L), class = c("tbl_df", "tbl", "data.frame"))

1 Ответ

0 голосов
/ 09 октября 2019

Вот подход, использующий tidyr для увеличения длины данных, затем объединение и повторное расширение.

df1 %>%
  rowid_to_column() %>%
  pivot_longer(-rowid, "col", values_to =  "brands") %>%
  stringdist_left_join(df2, method = "soundex") %>%

  # just keep first match, since real data won't have multiples
  group_by(rowid, col) %>%
  slice(1) %>%

  # tidying steps to make clean column titles
  rename("orig" = brands.x,
         "a" = brands.y) %>%
  gather(col2, val, c(orig, a)) %>%
  unite(col, c(col,col2))  %>%

  # make data wide again
  pivot_wider(names_from = col, values_from = val)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...