Трудно найти одно решение, подходящее для всех.Это потому, что строки, которые кажутся похожими, могут описывать очень разные вещи (например, Гранада против Гренады).Комментарии под оригинальным постом стоит изучить.
См. «Приблизительное совпадение строк» в Википедии (также иногда называемое «нечеткое сопоставление»).Есть много способов определить «похожие» на строки, как вы можете видеть.
Основным инструментом является функция R adist
.Он рассчитывает так называемое расстояние редактирования.
x <- c("American Indian and Alaska Native" ,
"Asian" ,
"Black of African American" ,
"Black or African American" ,
"Other" ,
"Unknown" ,
"white or Caucasian" ,
"White or Caucasian" ,
"White or Caucasion" )
u <- unique(x)
# compare all strings against each other
d <- adist(u)
# Do not list combinations of similar words twice
d[lower.tri(d)] <- NA
# Say your threshold below which you want to consider strings similar is
# 2 edits:
a <- which(d > 0 & d < 2, arr.ind = TRUE)
a
## row col
## [1,] 3 4
## [2,] 7 8
## [3,] 8 9
pairs <- cbind(u[a[,1]], u[a[,2]])
pairs
## [,1] [,2]
## [1,] "Black of African American" "Black or African American"
## [2,] "white or Caucasian" "White or Caucasian"
## [3,] "White or Caucasian" "White or Caucasion"
Но, в конце концов, вам придется самостоятельно оценивать результаты, чтобы избежать случайного выравнивания неравных факторов.
Вы можете сделать это воспроизводимо, используя именованный вектор в качестве словаря перевода.Например, взглянув на приведенный выше пример, я мог бы создать следующий словарь:
dict <- c(
# incorrect spellings correct spellings
# ------------------------- ----------------------------
"Black of African American" = "Black or African American",
"white or Caucasian" = "white or Caucasian" ,
"White or Caucasion" = "White or Caucasian"
)
# The correct levels need to be included, to
dict <- c(dict, setNames(u,u)
Затем преобразовать столбец фактора в символ с помощью as.character
и применить к нему словарь, как я делаю здесь с оригиналом.символьный вектор x
:
xcorrected <- dict[x]
# show without names, but the result is also correct if you just use
# xcorrected alone (remove as.character here to see the difference).
as.character(xcorrected)
[1] "American Indian and Alaska Native" "Asian"
[3] "Black or African American" "Black or African American"
[5] "Other" "Unknown"
[7] "white or Caucasian" "White or Caucasian"
[9] "White or Caucasian"