Назначьте категорию для каждой строки df на основе частичного совпадения с вектором строки R - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть

mydf <- data.frame(menu = c("chicken with peanut sauce", "sole and clam chowder", "shrimp salad"), category = NA)                
allergens1 <- c("peanut", "walnut", "cashew", "fava bean", "almond")
allergens2 <- c("scallops", "shrimp")

Я хотел бы изменить категорию на произвольную строку, которую я определяю (например, орехи), если какой-либо элемент в аллергенах обнаружен в строках меню. Таким образом, результат будет следующим:

menu                          category
chicken with peanut sauce      nuts
sole and clam chowder          NA
shrimp salad                   shellfish

Оператор% in% здесь не выглядит полезным, так как «mydf $ menu% in% аллергены» приводит к «False», «False», поскольку все строки в Меню не соответствует ни одному из пунктов в аллергенах. Я думаю, что grepl может быть полезным, но не уверен, как обращаться к вектору. Я мог бы кодировать каждый элемент вектора аллергенов в поиске заменить регулярное выражение на "|" но я думаю, что, возможно, есть более чистый способ кодирования этого.

1 Ответ

0 голосов
/ 03 февраля 2020

Мы можем использовать grep / grepl здесь, вставив строку allergens1 и allergens2 вместе в один шаблон. Если menu соответствует любому элементу в allergens1, мы присваиваем значение "nuts", а если соответствует любому элементу в allergens2, мы присваиваем "shellfish" category.

mydf$category[grep(paste0('\\b', allergens1, '\\b', collapse = '|'), mydf$menu)] <- 'nuts'
mydf$category[grep(paste0('\\b', allergens2, '\\b', collapse = '|'), mydf$menu)] <- 'shellfish'
mydf

#                       menu  category
#1 chicken with peanut sauce      nuts
#2     sole and clam chowder      <NA>
#3              shrimp salad shellfish

Мы также можем использовать case_when с str_detect, чтобы сделать это tidyverse способом.

library(dplyr)
library(stringr)

mydf %>%
  mutate(category  = case_when(
   str_detect(menu, str_c('\\b', allergens1, '\\b', collapse = '|'))~'nuts', 
   str_detect(menu, str_c('\\b', allergens2, '\\b', collapse = '|'))~'shellfish'))

Мы добавляем границы слов (\\b), чтобы избежать совпадения "cashew" с "cashewnut". Удалите их, если вы хотите, чтобы они были сопоставлены.

...