Как заменить список слов с ошибками списком правильных слов? - PullRequest
0 голосов
/ 31 января 2019

Я пытаюсь понять, как заменить длинный список слов с ошибками из списка правильных слов, но не уверен, как это сделать.Пожалуйста, сообщите, если это возможно.Спасибо.

Я пробовал str_replace и gsub, но похоже, потому что я хочу реализовать изменения из фрейма данных, чтобы он не работал таким образом.

df = tibble(Movie_Name = list("Black Panthet", "Irom Man", "Captain Anerica", "Black Panthers", "Iron Men", "Captain America", "Avangers"))

correct = tibble(correct_movie_name = list("Black Panther", "Iron Man", "Captain American", "Avengers"))

Я ожидаювывод будет таким:

df = tibble(Movie_Name = list("Black Panther", "Iron Man", "Captain America", "Black Panther", "Iron Man", "Captain America", "Avengers"))

Ответы [ 4 ]

0 голосов
/ 31 января 2019

Вот решение, основанное на ответах @ G5W и avid_useR

library(tidyverse)
library(stringdist)

Movie_Name = list("Black Panthet", "Irom Man", "Captain Anerica", "Black Panthers", "Iron Men", "Captain America", "Avangers")

correct_movie_name = list("Black Panther", "Iron Man", "Captain America", "Avengers")

New_Movie_name <- lapply(Movie_Name, function(x) {
  lapply(correct_movie_name, function(y) {
    stringdist(x,y)
  }) %>% unlist() %>% which.min() %>% correct_movie_name[[.]]
})

# New_Movie_name is a list of the same length as Movie_Name but with correct movie names based on elements in list correct_movie_name
0 голосов
/ 31 января 2019

Я не думаю, что есть идеальное решение для этого.Лучшее, что можно сделать, - это рассчитать какое-то расстояние редактирования между Movie_Name и correct_movie_name и заменить его словом из correct_movie_name с наименьшим расстоянием.Какой показатель использовать, во многом зависит от ситуации, и требуется много настроек.Здесь я использовал функцию stringdist из пакета stringdist, которая имеет различные метрики расстояния, которые вы можете выбрать.По умолчанию используется «ограниченное расстояние Дамерау-Левенштейна» (от ?stringdist).Мы также можем использовать levenshsteinDist из RecordLinkage пакета:

library(dplyr)
library(stringdist)
library(RecordLinkage)

replace_names <- function(vec, replace_list, dist_func){
  map_chr(vec, ~{
    replace_list[which.min(dist_func(.x, replace_list))]
  })
}

df %>%
  mutate(Correct_stringdist = replace_names(Movie_Name, correct$correct_movie_name, stringdist),
         Correct_levenshsteinDist = replace_names(Movie_Name, correct$correct_movie_name, levenshteinDist))

Выход:

# A tibble: 7 x 3
  Movie_Name      Correct_stringdist Correct_levenshsteinDist
  <chr>           <chr>              <chr>                   
1 Black Panthet   Black Panther      Black Panther           
2 Irom Man        Iron Man           Iron Man                
3 Captain Anerica Captain American   Captain American        
4 Black Panthers  Black Panther      Black Panther           
5 Iron Men        Iron Man           Iron Man                
6 Captain America Captain American   Captain American        
7 Avangers        Avengers           Avengers 
0 голосов
/ 31 января 2019

Функция agrep позволяет выполнять приблизительное сопоставление между строками.

df = tibble(Movie_Name = list("Black Panthet", "Irom Man", "Captain Anerican", "Black Panthers", "Iron Men", "Captain America", "Avangers"))

correct = tibble(correct_movie_name = list("Black Panther", "Iron Man", "Captain America", "Avengers"))

df2 = tibble( Movie_Name = sapply(df$Movie_Name, function(x){
                  for(i in correct$correct_movie_name){
                    comparison <- agrep(i, x)
                    if(length(comparison) != 0){
                      if(comparison == 1){
                      return(i)
                    }}
                  }
                  return(x)
                }))
0 голосов
/ 31 января 2019

Одним из способов может быть использование расстояния Левенштейна, которое доступно из пакета stringdist.

library(stringdist)

MovieNames   = unlist(df$Movie_Name)
CorrectNames = unlist(correct$correct_movie_name)

for(MN in MovieNames) {
    CMN = which.min(stringdist(CorrectNames,  MN, method = "lv"))
    cat(MN, " should be ",  CorrectNames[CMN], "\n")
}

Black Panthet  should be  Black Panther 
Irom Man  should be  Iron Man 
Captain Anerica  should be  Captain American 
Black Panthers  should be  Black Panther 
Iron Men  should be  Iron Man 
Captain America  should be  Captain American 
Avangers  should be  Avengers 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...