Создание цикла grep для поиска значений символов, а затем сопоставления совпадений в новом столбце

#r #loops

#r #циклы

Вопрос:

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

 df<- data.frame("Restaurant" = c("Dominos Pizza", "Papa Johns Pizza", "Dairy Queen Ice Cream", "Dennys Breakfast")
  

Я пробовал:

 tags<- c("Pizza", "Breakfast", "Cream")

for (i in length(tags)) {
df$i <- df[grep(i, df$Restaurant),]
  
}
  

Я хочу, чтобы мой желаемый результат был:

Ресторан Dominos Pizza Pappa Johns Пицца Мороженое Dairy Queen

введите описание изображения здесь

Затем я могу расплавить df для создания сопоставления

Ответ №1:

Попробуйте это. Вы можете использовать ifelse() и grepl() для проверки условий, а затем использовать те же tags значения для создания новых переменных. Здесь код:

 #Data
df<- data.frame("Restaurant" = c("Dominos Pizza", "Papa Johns Pizza", "Dairy Queen Ice Cream", "Dennys Breakfast"),stringsAsFactors = F)
tags<- c("Pizza", "Breakfast", "Cream")
#Loop
for(i in 1:length(tags))
{
  df[[tags[i]]] <- ifelse(grepl(tags[i],df$Restaurant),df$Restaurant,NA)
}
  

Вывод:

 df
             Restaurant            Pizza        Breakfast                 Cream
1         Dominos Pizza    Dominos Pizza             <NA>                  <NA>
2      Papa Johns Pizza Papa Johns Pizza             <NA>                  <NA>
3 Dairy Queen Ice Cream             <NA>             <NA> Dairy Queen Ice Cream
4      Dennys Breakfast             <NA> Dennys Breakfast                  <NA>
  

Ответ №2:

Вот мысль, цикл не требуется:

 # add the closing paren
df<- data.frame("Restaurant" = c("Dominos Pizza", "Papa Johns Pizza", "Dairy Queen Ice Cream", "Dennys Breakfast"))
tags<- c("Pizza", "Breakfast", "Cream")

df <- cbind(df, sapply(tags, grepl, df$Restaurant))
df
#              Restaurant Pizza Breakfast Cream
# 1         Dominos Pizza  TRUE     FALSE FALSE
# 2      Papa Johns Pizza  TRUE     FALSE FALSE
# 3 Dairy Queen Ice Cream FALSE     FALSE  TRUE
# 4      Dennys Breakfast FALSE      TRUE FALSE
  

Отсюда не так уж сложно заменить логические данные реальными строками:

 df[,-1] <- lapply(df[,-1], function(lgl) replace(df$Restaurant, !lgl, values = NA_character_))
df
#              Restaurant            Pizza        Breakfast                 Cream
# 1         Dominos Pizza    Dominos Pizza             <NA>                  <NA>
# 2      Papa Johns Pizza Papa Johns Pizza             <NA>                  <NA>
# 3 Dairy Queen Ice Cream             <NA>             <NA> Dairy Queen Ice Cream
# 4      Dennys Breakfast             <NA> Dennys Breakfast                  <NA>
  

Альтернативы, которые делают почти то же самое. Начиная с 1 столбца df :

 cbind(df, lapply(setNames(nm = tags), function(tg) replace(df$Restaurant, !grepl(tg, df$Restaurant), NA_character_)))
#              Restaurant            Pizza        Breakfast                 Cream
# 1         Dominos Pizza    Dominos Pizza             <NA>                  <NA>
# 2      Papa Johns Pizza Papa Johns Pizza             <NA>                  <NA>
# 3 Dairy Queen Ice Cream             <NA>             <NA> Dairy Queen Ice Cream
# 4      Dennys Breakfast             <NA> Dennys Breakfast                  <NA>
  

или

 cbind(df, lapply(setNames(nm = tags), function(tg) ifelse(grepl(tg, df$Restaurant), df$Restaurant, NA_character_)))
#              Restaurant            Pizza        Breakfast                 Cream
# 1         Dominos Pizza    Dominos Pizza             <NA>                  <NA>
# 2      Papa Johns Pizza Papa Johns Pizza             <NA>                  <NA>
# 3 Dairy Queen Ice Cream             <NA>             <NA> Dairy Queen Ice Cream
# 4      Dennys Breakfast             <NA> Dennys Breakfast                  <NA>

  

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

1. Большое спасибо, первый набор кода работает отлично, но второй возвращает эту ошибку Ошибка meassage в !lgl: недопустимый тип аргумента

2. Не уверен, что сказать … это работает для меня, когда столбцы имеют класс logical . str(df) Предполагает, что Pizza (etc) все логические? Вы должны увидеть Pizza : logi ... .

3. Да, это так, код выполняется без! перед lgl, но, очевидно, не правильный вывод

4. хорошо, есть ли другие столбцы, которыми вы не поделились? df[,-1] означает каждый столбец, кроме первого ( $Restaurant ), возможно, вы используете слишком много столбцов? Попробуйте df[,2:4] <- lapply(df[,2:4], ...)

5. Я могу воспроизвести эту ошибку только тогда, когда логические столбцы больше не являются логическими. Например, если вы запустите мой код выше (с моими данными… работайте со мной здесь) с df <- data.frame(...) конца df[,-1] <- lapply(...) , затем повторите эту последнюю lapply команду, я вижу ошибку. Если вы случайно запустили его дважды, эта ошибка верна, не делайте этого. Если вы используете слишком много столбцов, укажите более конкретно (в своем коде), какие столбцы, а не только -1 . Какие бы изменения вы ни вносили в индексы столбцов в LHS, делайте это и в RHS.