我有这个玩具数据df:
structure(list(Product_Name = c("Delicious Chips", "Creamy Tomato Soup",
"Cheesy Macaroni", "Savory Meatballs", "Crispy Chicken Tenders"
), Ingredients = c("Potato Slices | Vegetable Oil | Salt | Seasoning Blend",
"Tomatoes | Water | Cream | Onions | Salt | Spices", "Macaroni | Cheese Sauce | Milk | Butter | Salt | Pepper",
"Ground Meat | Breadcrumbs | Onions | Garlic | Spices", "Chicken Tenders | Breading Mix | Vegetable Oil | Salt | Pepper"
)), row.names = c(NA, 5L), class = "data.frame")
Run Code Online (Sandbox Code Playgroud)
这里我想找到变量"Salt"中包含哪些行Ingredients。
使用library(tidyverse),最初我尝试df %>% str_detect(Ingredients, "Salt")但我得到了Error: object 'Ingredients' not found。
但是当我将其更改为df %>% filter(str_detect(Ingredients, "Salt")它时,它会返回一个数据帧,其中包含与字符串匹配的产品。
我认为str_detect需要一个字符向量或可强制转换为字符向量的东西,我认为这Ingredients很适合,因为当我这样做时class(df$Ingredients)它会返回字符。为什么它不作为Ingredients参数,当它被包装到 中时会发生什么变化filter()?
在许多 Tidyverse(例如 dplyr)函数中,传递给函数的未加引号的变量使用数据屏蔽,这允许您使用未加引号的数据变量,就好像它们是环境中的变量一样。当我们使用时我们可以看到这一点dplyr::filter:
library(dplyr)
df |>
filter(Product_Name == "Savory Meatballs")
#> Product_Name Ingredients
#> 1 Savory Meatballs Ground Meat | Breadcrumbs | Onions | Garlic | Spices
Run Code Online (Sandbox Code Playgroud)
这里filter是在 中查找并使用变量“Product_Name” df,而不是在全局环境中。
但是,str_detect以及 stringr 包中的大多数其他函数不具备此功能。正如其他人所指出的,您可以将调用str_detect嵌套在mutate或中filter以查看这些结果。但如果您只想传递Ingredients给 str_detect,您可以使用该with函数(有关r-bloggers 的更多信息)。看起来是这样的:
library(stringr)
df |>
with(str_detect(Ingredients, "Salt"))
#> [1] TRUE TRUE TRUE FALSE TRUE
Run Code Online (Sandbox Code Playgroud)
它所做的事情与那些 dplyr 函数在幕后所做的事情非常相似:而不是在全局环境中寻找名为“Ingredients”的变量(未定义,因为这不是你想要的,你希望它寻找df) 中的“Ingredients”,它将第一个参数 ( df) 视为自己的环境,并在该环境中查找名为“Ingredients”的变量。