R 如何在case_when语句中检测多个正则表达式

R 如何在case_when语句中检测多个正则表达式,r,R,最近,我从dplyr将ifelse转换为case\u 目标 我希望能够在数据帧中使用case_(当时)从语句中检测多个正则表达式,如下所示: 输入 statement<-data.frame(statement = c("I have performed APC and RFA", "An EMR was done","I didn't do anything"),stringsAsFactors=FALSE) statement

最近,我从
dplyr
将ifelse转换为
case\u

目标

我希望能够在数据帧中使用
case_(当
时)从语句中检测多个正则表达式,如下所示:

输入

statement<-data.frame(statement = c("I have performed APC and RFA",
 "An EMR was done","I didn't do anything"),stringsAsFactors=FALSE)
statement                            out

I have performed APC and RFA        APC,RFA
An EMR was done                     EMR
I didn't do anything                No Event
library(dplyr)
library(stringr)

      dataframe <- 
        dataframe %>% 
        mutate(
          EVENT = case_when(
            str_detect(statement,"EMR") ~ "EMR", 
            str_detect(statement, "HALO|RFA") ~ "RFA", 
            str_detect(statement, "APC") ~ "APC", 
             TRUE ~ "No Event"
          )
        )
尝试

statement<-data.frame(statement = c("I have performed APC and RFA",
 "An EMR was done","I didn't do anything"),stringsAsFactors=FALSE)
statement                            out

I have performed APC and RFA        APC,RFA
An EMR was done                     EMR
I didn't do anything                No Event
library(dplyr)
library(stringr)

      dataframe <- 
        dataframe %>% 
        mutate(
          EVENT = case_when(
            str_detect(statement,"EMR") ~ "EMR", 
            str_detect(statement, "HALO|RFA") ~ "RFA", 
            str_detect(statement, "APC") ~ "APC", 
             TRUE ~ "No Event"
          )
        )
库(dplyr)
图书馆(stringr)
数据帧%
变异(
事件=发生时的情况(
str_detect(语句“EMR”)~“EMR”,
str|u detect(语句“HALO | RFA”)~“RFA”,
str_detect(语句“APC”)~“APC”,
TRUE~“无事件”
)
)
问题


如果存在多个字符串,则每个语句只提供一个输出,而不是多个输出。有没有一种方法可以检测多个字符串?

通过base R提取所有大写字母的单词,并粘贴大于1个字符的单词,即

sapply(regmatches(statement$statement, gregexpr('\\b[A-Z]+\\b', statement$statement)), 
                                          function(i) {
                                                      v1 <- i[nchar(i) > 1];
                                                      toString(v1)
                                                      })


#[1] "APC, RFA" "EMR"      ""
sapply(regmatches(语句$statement,gregexpr('\\b[A-Z]+\\b',语句$statement)),
职能(一){
v1];
toString(v1)
})
#[1] APC,RFA“EMR”
1)gsubfn::Straply
Straply可以一次完成提取和翻译
Straply
将针对
stmt
的每个组件,将模式
pat
与之匹配,所有匹配项将使用L转换,然后返回。
empty
参数定义没有匹配项的
stat
组件返回的内容。这将提供一个匹配列表,每行一个列表组件,在该列表上应用
toString
将每个匹配转换为逗号分隔的字符串。这是这里介绍的3个备选方案中最短的一个

library(gsubfn)

L <- list(APC = "APC", EMR = "EMR", HALO = "RFA", RFA = "RFA")
pat <- paste(names(L), collapse = "|")
transform(statement, 
  out = sapply(strapply(stmt, pat, L, empty = "No Event"), toString),
  stringsAsFactors = FALSE)
2)基R使用上面的
L
pat
,创建一个函数,该函数获取单词
x
的字符向量,并将那些与
pat
匹配的单词提取到
g
。如果
g
长度非零,则使用
L
转换其元素,并使用
toString
将其压缩为单个字符串;否则,返回
无事件

现在使用
strsplit
stmt
的每个元素拆分为单词,并对每个这样的字符向量应用
process

process <- function(x) {
  g <- grep(pat, x, value = TRUE)
  if (length(g)) toString(L[g]) else "No Event"
}
transform(statement, out = sapply(strsplit(stmt, "\\s+"), process),
  stringsAsFactors = FALSE)
给予:

                          stmt      out
1 I have performed APC and RFA APC, RFA
2              An EMR was done      EMR
3         I didn't do anything No Event
# A tibble: 3 x 2
  stmt                         out     
  <chr>                        <chr>   
1 I have performed APC and RFA APC, RFA
2 An EMR was done              EMR     
3 I didn't do anything         No Event
#一个tible:3 x 2
退出
1我执行过APC和RFA APC、RFA
2进行了电子病历
3.我什么都没做没有
注 我们将其用作输入:

statement <- structure(list(stmt = c("I have performed APC and RFA", 
  "An EMR was done", "I didn't do anything")), 
  class = "data.frame", row.names = c(NA, -3L))

语句当
满足条件时,
case\u的逻辑是,它不会执行剩余的条件,因此当
语句满足条件时,实际上无法从
case\u获得两个输出。因此,如果您想在
时使用
case_,建议从最不常见的情况开始,然后慢慢地继续使其更通用。(因此,
TRUE
是最后一个条件)

如果您想在
时坚持使用
case\u,您可以添加一个附加条件,分别检查这两种情况,并给出相应的输出

library(dplyr)

statement %>% 
     mutate(
     EVENT = case_when(
           str_detect(statement, "APC") & str_detect(statement, "RFA") ~ "APC,RFA",
           str_detect(statement,"EMR") ~ "EMR", 
           str_detect(statement, "HALO|RFA") ~ "RFA", 
           str_detect(statement, "APC") ~ "APC", 
           TRUE ~ "No Event"
            )
           )



#                     statement    EVENT
#1 I have performed APC and RFA  APC,RFA
#2              An EMR was done      EMR
#3         I didn't do anything No Event
#4                        FALSE No Event

我不认为当
是最好的方式时case\u。我认为这取决于有多少映射,比如
“HALO | RFA”
。如果有很多函数,那么花时间编写一个合适的函数可能是值得的。但是,如果只是这一个,那么使用dplyr动词组合管道可能会更快

我建议使用
str\u extract\u all
unnest
获得一个包含相关动词的整洁数据框,然后使用
str\u replace\u all
解决映射问题。最后,我将使用
unique
确保替换中没有重复的行

请注意,带有APC、RFA的第一列将一分为二。我意识到这不是你所要求的,但它将使tidyverse中的后续处理更加容易。有关整洁数据约定的更多信息,请参见此链接:

在它的当前实现中,
unest
将删除没有匹配模式的最后一行。如果您希望使用
NA
,则可以对原始数据执行
完全联接。另见

语句%mutate(
out=语句%>%
str|u extract|u all(((EMR)|(HALO)|(RFA)|(APC)))
)%%>%unnest(.drop=FALSE)%%>%
变异(
out=out%>%str\u替换所有(“光环”、“RFA”)
) %>% 
唯一()%>%
完全联接(语句)
输出将是

                 statement    out
I have performed APC and RFA  APC
I have performed APC and RFA  RFA
An EMR was done               EMR
I didn't do anything          <NA>
语句输出
我执行过APC和RFA APC
我执行过APC和RFA RFA
进行电子病历
我什么都没做

输出仅给出一个结果。例如,第一个文本字符串仅输出apcthreak@RonakShah。不幸的是,这并不是一个可伸缩的答案,我不想创建str_detect的每一个排列,如果它确实向上扩展@G.Grothendieck。我有类似的情况,但有点不同。当
时,我得到了一个奇怪的结果。我的case\u when语句是这样的:
mutate(EVENT=case\u when(str\u detect(语句,“30多个条件”)~“EMR”,str\u detect(语句,“30多个条件”)~“RFA”,str\u detect(语句,“30多个条件”)~“APC”,TRUE~“语句”)
在这种情况下我该怎么办?@Wialliam,你不能多次使用同一个条件。如果第一个条件为true,它将返回其右侧,如果为false,所有条件都将为false,它将返回默认值。因此,后续的重复条件永远不会匹配。建议你阅读
?c