2016-01-24 2 views
1

любая помощь по моей проблеме будет очень оценена, спасибо.sapply функция ifelse на символьных векторах различной длины [r]

У меня есть кадр данных, где второй столбец имеет «выбранные» слова, извлеченные из первого столбца (на предыдущих шагах), которые теперь часто (но не всегда) оставляют их в другом рабочем порядке. Теперь мне нужно получить слова в столбце «wordDF $ subbed» в том же рабочем порядке, что и в столбце «wordsDF $ original».

Я разместил небольшое подмножество, чтобы проиллюстрировать четвертый столбец (wordDF $ target), который я выполнил вручную, чтобы продемонстрировать свою цель.

Я пытаюсь создать третий столбец (wordsDF $ reord), который будет словом `wordsDF $ subbed 'в том порядке, в котором они найдены в' wordsDF $ original ', используя sapply(). Я застрял на том, как передать функцию sapply по всем словам строк слова DF $ original, которые имеют разную длину (т. Е. Количество слов в каждой строке). Единственный способ, которым я могу достичь этого, - использовать функцию strr str_detect для определения (слева направо), если каждое слово в словахDF $ original находится в словах DF $ subbed, и если «да», чтобы извлечь это слово в wordDF $ reord (вставлен с чем-либо уже извлеченным). Если «нет», то слово columnDF $ остается неизменным.

Мое решение ниже, однако, оно жестко закодировано только для проверки и извлечения первого слова. Может кто-нибудь, пожалуйста, покажите мне, как я передаю функцию вдоль каждой строки, пожалуйста? Или существует гораздо лучший подход, который переупорядочивает подсловы wordsDF $ и отменяет необходимость в wordDF $ reord?

library(stringr) 

original = c("heat pump only for 100/150l geyser r410a gas", 
     "alliance allwh 5_dcpt_0kw heat pump only for 200/25", 
     "alliance allwinteg 190l integrated heat pump and cylinder r134a gas", 
     "aquatouch bt10 cp bottle trap 32x40", 
     "aquatouch pop32lux cp slotted pop up basin waste 32mm", 
     "aquatouch ci15 cp angle regulating valve only 15x15") 

subbed = c("heat pump", 
     "heat pump", 
     "and cylinder heat pump", 
     "bottle trap", 
     "basin pop up waste", 
     "valve") 


wordsDF = as.data.frame(cbind(original, subbed)) 
wordsDF$original = as.character(wordsDF$original) 
wordsDF$subbed = as.character(wordsDF$subbed) 
wordsDF$reord = character(nrow(wordsDF)) 
wordsDF$target = c("heat pump","heat pump", 
       "heat pump and cylinder", 
       "bottle trap","pop up basin waste", 
       "valve") 

# my attempted solution... 
wordsDF$reord = sapply(wordsDF$original, function(x) ifelse(
      test = str_detect(wordsDF$subbed, word(wordsDF$original, 1,1)), 
      yes = paste(wordsDF$reord, str_extract(wordsDF$subbed, word(wordsDF$original, 1,1))), 
      no = wordsDF$reord)) 

благодарит заранее!

ответ

2

Вот возможная база R решение, которое работает mapply над обоими расщепленных векторов и возвращает совпавшие слова между ними в правильном порядке, завернутые в paste

Rematch <- function(x, y) paste(y[sort(match(x, y))], collapse = " ") # Define an helper functions 
mapply(Rematch, strsplit(subbed, "\\s+"), strsplit(original, "\\s+")) 
# [1] "heat pump"    "heat pump"    "heat pump and cylinder" "bottle trap"   "pop up basin waste"  
# [6] "valve" 
+1

Это ударил гвоздь твердо на голове. Многое спасибо @David. – CallumH

+0

В качестве альтернативы вы можете определить 'Rematch <- function (x, y) paste (x [match (y, x, nomatch = 0)], collapse =" ")'. Кроме того, если всегда есть одно пространство, вы можете повысить производительность, указав 'sep =" "и' fixed = TRUE' в обоих вызовах strsplit (вместо '" \\ s + "') –

Смежные вопросы