R 使用case_进行字符串匹配的多个模式
我尝试使用str_detect和case_根据多个模式重新编码字符串,并将每次发生的重新编码值粘贴到一个新列中。正确的列是我试图实现的输出 这与case_类似,如果不能使用case_(我认为仅限于一种模式),是否还有更好的方法可以使用tidyverse实现这一点R 使用case_进行字符串匹配的多个模式,r,tidyverse,case-when,R,Tidyverse,Case When,我尝试使用str_detect和case_根据多个模式重新编码字符串,并将每次发生的重新编码值粘贴到一个新列中。正确的列是我试图实现的输出 这与case_类似,如果不能使用case_(我认为仅限于一种模式),是否还有更好的方法可以使用tidyverse实现这一点 Fruit=c("Apples","apples, maybe bananas","Oranges","grapes w apples","pears") Num=c(1,2,3,4,5) data=data.frame(Num,Fru
Fruit=c("Apples","apples, maybe bananas","Oranges","grapes w apples","pears")
Num=c(1,2,3,4,5)
data=data.frame(Num,Fruit)
df= data %>% mutate(Incorrect=
paste(case_when(
str_detect(Fruit, regex("apples", ignore_case=TRUE)) ~ "good",
str_detect(Fruit, regex("bananas", ignore_case=TRUE)) ~ "gross",
str_detect(Fruit, regex("grapes | oranges", ignore_case=TRUE)) ~ "ok",
str_detect(Fruit, regex("lemon", ignore_case=TRUE)) ~ "sour",
TRUE ~ "other"
),sep=","))
Num Fruit Incorrect
1 Apples good
2 apples, maybe bananas good
3 Oranges other
4 grapes w apples good
5 pears other
在情况下_当一行满足条件时,它将停止在那里,不再检查任何其他条件。因此,通常在这种情况下,最好将每个条目放在单独的行中,以便更容易赋值,然后将它们汇总在一起。但是,在本例中,
水果
列没有清晰的分隔符,有些水果用逗号(,
)分隔,有些水果用空格分隔,它们之间还有其他单词。为了处理所有此类情况,我们为不匹配的单词指定NA
,然后在总结过程中删除它们
library(dplyr)
library(stringr)
data %>%
tidyr::separate_rows(Fruit, sep = ",|\\s+") %>%
mutate(Correct = case_when(
str_detect(Fruit, regex("apples", ignore_case=TRUE)) ~ "good",
str_detect(Fruit, regex("bananas", ignore_case=TRUE)) ~ "gross",
str_detect(Fruit, regex("grapes|oranges", ignore_case=TRUE)) ~ "ok",
str_detect(Fruit, regex("lemon", ignore_case=TRUE)) ~ "sour",
TRUE ~ NA_character_)) %>%
group_by(Num) %>%
summarise(Correct = toString(na.omit(Correct))) %>%
left_join(data)
# Num Correct Fruit
# <dbl> <chr> <fct>
#1 1 good Apples
#2 2 good, gross apples, maybe bananas
#3 3 ok Oranges
#4 4 ok, good grapes w apples
#5 5 sour Lemons
库(dplyr)
图书馆(stringr)
数据%>%
tidyr::分开的_行(水果,sep=“,| \\s+”)%>%
变异(正确=当(
str_detect(水果,正则表达式(“apples”,ignore_case=TRUE))~“good”,
str_detect(水果,正则表达式(“香蕉”,忽略大小写=TRUE))~“gross”,
str|u detect(水果,regex(“葡萄|橙子”,忽略| case=TRUE))~“ok”,
str_detect(水果,正则表达式(“柠檬”,忽略大小写=TRUE))~“酸”,
真~NA_字符(u))%>%
分组依据(Num)%>%
总结(正确=toString(不正确)(省略)(正确))%>%
左联合(数据)
#正确的水果
#
#1个好苹果
#2 2个好的,恶心的苹果,也许是香蕉
#3个橙子
#好的,好的葡萄和苹果
#5个酸柠檬
对于更新的数据,我们可以删除出现的额外单词和do
data %>%
mutate(Fruit = gsub("maybe|w", "", Fruit)) %>%
tidyr::separate_rows(Fruit, sep = ",\\s+|\\s+") %>%
mutate(Correct = case_when(
str_detect(Fruit, regex("apples", ignore_case=TRUE)) ~ "good",
str_detect(Fruit, regex("bananas", ignore_case=TRUE)) ~ "gross",
str_detect(Fruit, regex("grapes|oranges", ignore_case=TRUE)) ~ "ok",
str_detect(Fruit, regex("lemon", ignore_case=TRUE)) ~ "sour",
TRUE ~ "other")) %>%
group_by(Num) %>%
summarise(Correct = toString(na.omit(Correct))) %>%
left_join(data)
# Num Correct Fruit
# <dbl> <chr> <fct>
#1 1 good Apples
#2 2 good, gross apples, maybe bananas
#3 3 ok Oranges
#4 4 ok, good grapes w apples
#5 5 other pears
数据%>%
突变(果=gsub(“可能是w”,果))%>%
tidyr::分开的_行(水果,sep=“,\\s+\\s+”%>%
变异(正确=当(
str_detect(水果,正则表达式(“apples”,ignore_case=TRUE))~“good”,
str_detect(水果,正则表达式(“香蕉”,忽略大小写=TRUE))~“gross”,
str|u detect(水果,regex(“葡萄|橙子”,忽略| case=TRUE))~“ok”,
str_detect(水果,正则表达式(“柠檬”,忽略大小写=TRUE))~“酸”,
对~“其他”))%>%
分组依据(Num)%>%
总结(正确=toString(不正确)(省略)(正确))%>%
左联合(数据)
#正确的水果
#
#1个好苹果
#2 2个好的,恶心的苹果,也许是香蕉
#3个橙子
#好的,好的葡萄和苹果
#其他5个梨
唯一的问题是TRUE~NA\u字符
。我希望将有意义的非匹配字符串编码为TRUE~other
。我编辑了数据以更好地反映我的实际数据@RonakShah@W148SMH正如我在帖子中提到的,问题的产生是因为每个水果之间没有明确的分隔物。有时用逗号分隔,有时用空格分隔。所以我用这两个词分开了,但是已经有一些不匹配的词,比如可能
,w
。如果我们给出TRUE ~'other'
,那么这些单词也将被分配'other'
。如果我在开始时删除maybe
和w
,比如stru-replace(水果,“maybe | w”,”)
在删除这些单词之后,它仍然想添加other
@RonakShah@W148SMH对如果这些是唯一出现的单词,那么您可以删除它们。见更新的答案。完美!谢谢&
data %>%
mutate(Fruit = gsub("maybe|w", "", Fruit)) %>%
tidyr::separate_rows(Fruit, sep = ",\\s+|\\s+") %>%
mutate(Correct = case_when(
str_detect(Fruit, regex("apples", ignore_case=TRUE)) ~ "good",
str_detect(Fruit, regex("bananas", ignore_case=TRUE)) ~ "gross",
str_detect(Fruit, regex("grapes|oranges", ignore_case=TRUE)) ~ "ok",
str_detect(Fruit, regex("lemon", ignore_case=TRUE)) ~ "sour",
TRUE ~ "other")) %>%
group_by(Num) %>%
summarise(Correct = toString(na.omit(Correct))) %>%
left_join(data)
# Num Correct Fruit
# <dbl> <chr> <fct>
#1 1 good Apples
#2 2 good, gross apples, maybe bananas
#3 3 ok Oranges
#4 4 ok, good grapes w apples
#5 5 other pears