R версия ВПР с несколькими совпадениями в ячейке

#r #match #vlookup

#r #совпадение #ВПР

Вопрос:

У меня есть вектор с числами и таблица поиска. Я хочу, чтобы числа были заменены описанием из таблицы поиска.

Это легко, когда векторы являются прямыми, как в этом примере:

 > variable <- sample(1:5, 10, replace=T)
> variable
 [1] 5 4 5 3 2 3 2 3 5 2
> 
> lookup <- data.frame(var = 1:5, description=LETTERS[1:5])
> lookup
  var description
1   1           A
2   2           B
3   3           C
4   4           D
5   5           E
> 
> with(lookup, description[match(variable, var)])
 [1] E D E C B C B C E B
Levels: A B C D E
  

Однако, когда отдельные элементы вектора содержат несколько результатов, у меня возникают проблемы:

 variable <- c("1", "2^3", "1^5", "4", "4")
  

Я хотел бы, чтобы возвращаемый вектор выдавал:

 c("A", "B^C", "A^E", "D", "D")
  

Комментарии:

1. Вам не нужен простой vlookup (часто выполняемый как «слияние» или «объединение» в R / Python), поскольку вам нужны соответствия подстрокам. Я предлагаю вам изучить возможность разделения ваших сложных variable записей на отдельные элементы, объединить / join / vlookup, затем повторно объединить.

Ответ №1:

Если у вас есть только одно совпадение символов и замена, вы можете использовать chartr

 chartr(paste0(lookup$var, collapse = ""), 
       paste0(lookup$description, collapse = ""), variable)

#[1] "A"   "B^C" "A^E" "D"   "D"  
  

chartr в основном сообщает, что заменить

 paste0(lookup$var, collapse = "")
#[1] "12345"
  

с

 paste0(lookup$description, collapse = "")
#[1] "ABCDE"
  

Это также полезно, поскольку оно не изменяет и не возвращает NA для символов, которые не совпадают.

Ответ №2:

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

 sapply(strsplit(variable, "\^"), function(x) paste0(lookup$description[as.numeric(x)], collapse = "^"))
[1] "A"   "B^C" "A^E" "D"   "D"  
  

Ответ №3:

Вы можете использовать scan для преобразования текста в числовой формат, который затем можно использовать в качестве индекса для выбора элементов, которые затем можно свернуть вместе. Добавьте quiet = TRUE для подавления сообщений «Read».

 sapply(variable, function(t) { 
              paste( lookup$description[ scan(text=t, sep="^")], collapse="^")} )

Read 1 item
Read 2 items
Read 2 items
Read 1 item
Read 1 item
    1   2^3   1^5     4     4 
  "A" "B^C" "A^E"   "D"   "D"