代码之家  ›  专栏  ›  技术社区  ›  Ben G

如何使用R在另一个字符串向量中提取字符串向量的外观?

  •  2
  • Ben G  · 技术社区  · 8 年前

    我有一个这样的弦向量:

    strings <- tibble(string = c("apple, orange, plum, tomato",
                                 "plum, beat, pear, cactus",
                                 "centipede, toothpick, pear, fruit"))
    

    我有一个水果载体:

    fruits <- tibble(fruit =c("apple", "orange", "plum", "pear"))
    

    我想要的是一个data.frame/tibble和原始的 strings 数据框,包含原始列中所有水果的第二个列表或字符列。像这样的东西。

    strings <- tibble(string = c("apple, orange, plum, tomato",
                                 "plum, beat, pear, cactus",
                                 "centipede, toothpick, pear, fruit"),
                       match = c("apple, orange, plum",
                                 "plum, pear",
                                 "pear")
                      )
    

    我试过了 str_extract(strings, fruits) 我得到了一个清单,上面所有东西都是空白的,还有警告:

    Warning message:
    In stri_detect_regex(string, pattern, opts_regex = opts(pattern)):
    longer object length is not a multiple of shorter object length
    

    我试过了 str_extract_all(strings, paste0(fruits, collapse = "|")) 我得到和得到同样的警告信息。

    我看过这个 Find matches of a vector of strings in another vector of strings ,但这似乎没有帮助。

    任何帮助都将不胜感激。

    3 回复  |  直到 8 年前
        1
  •  2
  •   Kara Woo    8 年前

    这里有一个选择。首先我们将 string 列成单独的字符串(现在 "apple, orange, plum, tomato" 都是一个字符串)。然后我们将字符串列表与 fruits$fruit 列并将匹配值的列表存储在新的 fruits 列。

    library("tidyverse")
    strings <- tibble(
      string = c(
        "apple, orange, plum, tomato",
        "plum, beat, pear, cactus",
        "centipede, toothpick, pear, fruit"
      )
    )
    
    fruits <- tibble(fruit =c("apple", "orange", "plum", "pear"))
    
    strings %>%
      mutate(str2 = str_split(string, ", ")) %>%
      rowwise() %>%
      mutate(fruits = list(intersect(str2, fruits$fruit)))
    #> Source: local data frame [3 x 3]
    #> Groups: <by row>
    #> 
    #> # A tibble: 3 x 3
    #>   string                            str2      fruits   
    #>   <chr>                             <list>    <list>   
    #> 1 apple, orange, plum, tomato       <chr [4]> <chr [3]>
    #> 2 plum, beat, pear, cactus          <chr [4]> <chr [2]>
    #> 3 centipede, toothpick, pear, fruit <chr [4]> <chr [1]>
    

    于2018-08-07由 reprex package (第0.2.0版)。

        2
  •  2
  •   user5176207user5176207    8 年前

    下面是一个使用purr的例子

    strings <- tibble(string = c("apple, orange, plum, tomato",
                             "plum, beat, pear, cactus",
                             "centipede, toothpick, pear, fruit"))
    
    fruits <- tibble(fruit =c("apple", "orange", "plum", "pear"))
    
    extract_if_exists <- function(string_to_parse, pattern){
      extraction <- stringi::stri_extract_all_regex(string_to_parse, pattern)
      extraction <- unlist(extraction[!(is.na(extraction))])
      return(extraction)
    }
    
    strings %>%
      mutate(matches = map(string, extract_if_exists, fruits$fruit)) %>%
      mutate(matches = map(string, str_c, collapse=", ")) %>%
      unnest
    
        3
  •  1
  •   s_baldur    8 年前

    下面是base-R解决方案:

    strings[["match"]] <- 
      sapply(
        strsplit(strings[["string"]], ", "), 
        function(x) {
          paste(x[x %in% fruits[["fruit"]]], collapse = ", ")
        }
      )
    

    导致:

      string                            match              
      <chr>                             <chr>              
    1 apple, orange, plum, tomato       apple, orange, plum
    2 plum, beat, pear, cactus          plum, pear         
    3 centipede, toothpick, pear, fruit pear