【问题标题】:Matching strings in switch statementsswitch 语句中的匹配字符串
【发布时间】:2018-10-02 08:41:35
【问题描述】:

我想使用 switch 语句根据字符串的前两个字符进行分支。在下面显示的示例中,我想用“aabb”或“aacc”返回“Apple”

test<-c("aabb", "aacc", "bbbb")

foo <- Vectorize(function(a) {
      switch(as.character(a),
            "^aa" = "Apple",
            "bbbb" = "Grape",
            "Unknown")

}, "a")

> foo(test)
aabb      aacc      bbbb 
"Unknown" "Unknown"   "Grape" 

如果存在完全匹配,我可以使语句起作用,但我不知道如何仅使用前两个字符来获得匹配。也许有一种使用正则表达式的方法?如图所示,我尝试使用^ 来匹配字符串的开头(与grep 一起使用)但它不起作用。

我想我可以将嵌套的 ifelse 语句与 grepl 一起使用,但它可以使用 switch 吗?

【问题讨论】:

    标签: r string switch-statement


    【解决方案1】:

    根据手册,switch 是不可能的,因为它只允许完全匹配:

    开关(EXPR,...)

    如果 EXPR 计算结果为字符串,则匹配该字符串 (确切地说)... 中元素的名称。

    但你可以在dplyr 中使用case_when:

    foo <- function(x){
        dplyr::case_when(
            grepl('^aa', x) ~ 'Apple',
            x == 'bbbb' ~ 'Grape',
            TRUE ~ 'Unknown'
        )
    }
    foo(test)
    # [1] "Apple" "Apple" "Grape"
    

    【讨论】:

      【解决方案2】:

      使用substr()提取前两个字母;使用setNames() 传播全名而不是答案的缩写

      > X = setNames(substr(test, 1, 2), test)
      > sapply(X, switch, aa="Apple", bb = "Grape", "Unknown")
         aabb    aacc    bbbb 
      "Apple" "Apple" "Grape" 
      

      【讨论】:

        【解决方案3】:

        这可能有效:

        regex_switch<-function(.v,...)
        {
          e<-enexprs(...)
          i<-min(which(str_detect(.v,names(e))))
          eval(e[[i]],parent.frame())
        }
        
        > map_chr(
           c("aaaa","bb","aabbaa"),
           regex_switch,
           "^aa"="Apple","^bbbb"="Grape","^*$"="Unknown"
        )  
        [1] "Apple"   "Unknown" "Apple"  
        > 
        

        【讨论】:

          猜你喜欢
          • 2011-02-23
          • 1970-01-01
          • 1970-01-01
          • 2023-02-20
          • 1970-01-01
          • 2019-11-17
          • 2020-12-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多