r - 根据与字符串向量 R 的部分匹配为每个 df 行分配类别
问题描述
我有
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% allergens”会导致“False”“False”,因为菜单中的整个字符串与过敏原中的任何项目都不匹配。我认为 grepl 可能有用,但不确定如何引用向量。我可以在搜索中对过敏原向量的每个项目进行编码,将正则表达式替换为“|” 但我认为可能有一种更简洁的方式来编写代码。
解决方案
我们可以在这里使用grep
/通过将andgrepl
的字符串粘贴在一起作为一个模式。如果匹配中的任何项目,我们分配值,如果匹配我们分配给的任何项目。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
withstr_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"
。如果您希望它们匹配,请删除它们。
推荐阅读
- go - 从偏移量获取时区名称
- angular - 在 Angular 8 构建中创建大量构建文件的 import() 语句的问题
- macaulay2 - 如何以表格格式枚举所有Grassmannian及其索引以及k和n?
- html - HTML 文件不理解 Django 内容
- python - LeetCode Python3 函数注释在 Visual Studio Code 中不起作用
- python - 有没有办法将 PDF 中的数据刮成结构化的 JSON 格式?
- python - 由于路径中找不到点,Python pygraphviz 无法正常工作
- c - 用 C 模糊图像
- ruby-on-rails - 如何获取来自 Ruby TCP 服务器的请求的 IP 地址?
- python - 根据时间选择随机数有多安全?