В R используйте цикл if с agrep для присвоения значения

Список шаблонов выглядит так:

pattern <- c('aaa','bbb','ccc','ddd')

X пришел из df выглядит так:

df$X <- c('aaa-053','aaa-001','aab','bbb')

Что я пытался сделать: используйте agrep, чтобы найти совпадающее имя в шаблоне на основе df $ X, затем присвойте значение существующему столбцу «column2» на основе результата сопоставления, например, если «aaa-053» соответствует «aaa» , тогда "aaa" будет значением в "column2", если не совпадает, то вернет na в этом столбце.

for (i in 1:length(pattern)) {
 match <- agrep(pattern, df$X, ignore.case=TRUE, max=0)
 if agrep = TRUE {
   df$column2 <- pattern
 } else {df$column2 <- na
 }
}

Идеальный столбец2 в df выглядит так:

'aaa','aaa',na,'bbb'

person onemikeone    schedule 19.03.2021    source источник
comment
Как вы думаете, что должно произойти, когда aaa совпадает с вашим aab?   -  person r2evans    schedule 19.03.2021


Ответы (1)


agrep само по себе не даст вам многого, чтобы определить, что использовать при совпадении кратных. Например,

agrep(pattern[1], df$x)
# [1] 1 2 3

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

Вот альтернатива:

D <- adist(pattern, df$x, fixed = FALSE)
D
#      [,1] [,2] [,3] [,4]
# [1,]    0    0    1    3
# [2,]    3    3    2    0
# [3,]    3    3    3    3
# [4,]    3    3    3    3
D[D > 0] <- NA
D
#      [,1] [,2] [,3] [,4]
# [1,]    0    0   NA   NA
# [2,]   NA   NA   NA    0
# [3,]   NA   NA   NA   NA
# [4,]   NA   NA   NA   NA
apply(D, 2, function(z) which.min(z)[1])
# [1]  1  1 NA  2
pattern[apply(D, 2, function(z) which.min(z)[1])]
# [1] "aaa" "aaa" NA    "bbb"
person r2evans    schedule 19.03.2021
comment
Я думаю, что это работает для числовых данных, но мое условие основано на символьных значениях, поэтому я изначально пытался использовать agrep - person onemikeone; 29.03.2021
comment
Я понятия не имею, что вы имеете в виду. agrep работает со строками, а не с числами, как adist. Смысл этого ответа состоит в том, чтобы (1) продемонстрировать, что ваше предположение об одиночных совпадениях ошибочно; и (2) предложить методологию, чтобы попытаться смягчить этот недостаток. Числовая часть этого ответа находится по наименьшему расстоянию между строками, что должно указывать на наилучшее совпадение. Если вы хотите избежать чисел, то я предлагаю вам либо использовать данные, которые никогда не имеют риска перекрытия, как это делает ваш образец, либо разработать методы, которые гораздо более интуитивно понятны, чем сопоставление нечетких строк. Удачи! - person r2evans; 29.03.2021
comment
Другая точка зрения: учитывая ваши образцы данных, это дает ожидаемый ответ в виде строк. Есть ли другое условие или свойство данных, из-за которых этот код работает плохо? Есть ли другие данные, где это не работает? Если он не работает с вашими реальными данными, вы не можете ожидать ничего лучшего, если не улучшите свой вопрос, включив в него более репрезентативные выборочные данные. - person r2evans; 29.03.2021