代码之家  ›  专栏  ›  技术社区  ›  user1200

从多个字符串的grepl匹配返回匹配的字符串,而不是逻辑

  •  3
  • user1200  · 技术社区  · 7 年前

    目前,我在grepl中使用嵌套的ifelse函数来检查与数据帧中字符串向量的匹配情况,例如:

    # vector of possible words to match
    x <- c("Action", "Adventure", "Animation")
    
    # data
    my_text <- c("This one has Animation.", "This has none.", "Here is Adventure.")
    my_text <- as.data.frame(my_text)
    
    my_text$new_column <- ifelse (
      grepl("Action", my_text$my_text) == TRUE,
      "Action",
      ifelse (
        grepl("Adventure", my_text$my_text) == TRUE,
        "Adventure",
        ifelse (
          grepl("Animation", my_text$my_text) == TRUE,
          "Animation", NA)))
    
    > my_text$new_column
    [1] "Animation" NA          "Adventure"
    

    这只适用于少数元素(例如,这里的三个元素),但当可能的匹配项大得多(例如,150)时,我如何返回?嵌套的ifelse看起来很疯狂。我知道我可以像下面的代码那样一次grepl多个东西,但这只会返回一个逻辑提示,告诉我字符串是否匹配,而不是哪个匹配。我想知道匹配了什么(在多个匹配的情况下,任何匹配都可以。

    x <- c("Action", "Adventure", "Animation")
    my_text <- c("This one has Animation.", "This has none.", "Here is Adventure.")
    grepl(paste(x, collapse = "|"), my_text)
    
    returns: [1]  TRUE FALSE  TRUE
    what i'd like it to return: "Animation" ""(or FALSE) "Adventure"
    
    3 回复  |  直到 7 年前
        1
  •  5
  •   Benjamin    7 年前

    遵循模式 here base 解决方案

    x <- c("ActionABC", "AdventureDEF", "AnimationGHI")
    
    regmatches(x, regexpr("(Action|Adventure|Animation)", x))
    

    stringr 有一种更简单的方法

    library(stringr)
    str_extract(x, "(Action|Adventure|Animation)")
    
        2
  •  3
  •   Sujeet Pillai    7 年前

    只需在示例代码中直接使用regmatches,就会出现以下错误。

        my_text$new_column <-regmatches(x = my_text$my_text, m = regexpr(pattern = paste(x, collapse = "|"), text = my_text$my_text))
    
        Error in `$<-.data.frame`(`*tmp*`, new_column, value = c("Animation",  : 
      replacement has 2 rows, data has 3
    

    这是因为只有2个匹配项,它将尝试拟合包含3行的数据框列中的匹配值。

    my_text$new_column <-
    lapply(X = my_text$my_text, FUN = function(X){
      regmatches(x = X, m = regexpr(pattern = paste(x, collapse = "|"), text = X))
    })
    

    Table screenshot

    希望这有帮助。

        3
  •  0
  •   Andrew Gustar    7 年前

    这样就可以了。。。

    my_text$new_column <- unlist(              
                             apply(            
                                 sapply(x, grepl, my_text$my_text),
                                 1,
                                 function(y) paste("",x[y])))
    

    sapply 生成一个逻辑矩阵,显示 x 术语出现在列的每个元素中。这个 apply 对应于 TRUE 价值观(粘贴一个 "" 一开始是为了避免 NA 匹配一行后,它们将粘贴在输出中。