【问题标题】:Equivalent function to stringr::word in stringi packagestringi 包中 stringr::word 的等效函数
【发布时间】:2017-11-13 12:07:40
【问题描述】:

我翻阅了stringi 包手册,在stringr 包中找到了函数word() 的等价物,但我找不到。我正在寻找它的原因是因为我想为我的语言环境设置排序规则选项,而stringr 并没有给我stringi 提供的所有选项。 stringi 包中是否有与stringr 包中的 word() 函数相同的函数?请参阅下面的示例,我想要“José”一词之后的下三个单词,以不同的方式书写。在stringi 包中,函数stri_opts_collator 允许设置参数strength=1 以获得允许的排序强度,因此所有形式的“José”都会被考虑在内。

sentencas<-c("josé é um trabalhador responsável","José é um trabalhador 
responsável","jose é um trabalhador responsável","Jose é um trabalhador 
responsável")

sentencas %>% word(2,sep=coll("jose ",ignore_case=T)) %>% word(1,3)

使用stringi,我可以提取所有形式的“José”:

stri_extract_first_coll(sentencas,"jose",strength=1).

我想做这样的事情:

sentencas %>% word(2,sep=coll("jose ",strength=1)) %>% word(1,3)

【问题讨论】:

    标签: r stringr stringi


    【解决方案1】:

    stringr::word() 不完全相同,但这似乎可以解决问题:

    sentencas %>% 
      stri_split_coll("jose ", strength=1, simplify = TRUE) %>% 
      .[,2] %>% 
      word(1,3)
    

    【讨论】:

      【解决方案2】:

      这里是另一种选择。请注意,我在您的标记词之前引入了一些词以进行提取,即“Josè”,因为我假设您不仅会有以该词开头的句子。重要的功能是结合使用stri_locate 来检测标记词的结尾,添加一个字符位置,并将此位置与要传递给stri_sub 的字符串中的最后一个字符位置结合使用。请注意,提供的功能不是故障安全的,例如,对于零匹配的情况等。

      还请检查以下基准以了解迄今为止提出的三种解决方案。

      library(stringi)
      library(magrittr)
      
      sentencas<- c("some words josé é um trabalhador responsável"
                    ,"only one word José é um trabalhador responsável"
                   ,"several words jose é um trabalhador responsável"
                   ,"and again some words Jose é um trabalhador responsável")
      
      stri_word <- function(marker, str, words_after_marker) {
      
        stri_sub(str,  cbind(stri_locate_first_coll(str, marker ,strength=1)[, "end"]+1, nchar(str)) ) %>% 
        { gsub( "^\\s+|\\s+$", "", stri_extract_first_regex(., paste0("(\\s\\w+){", words_after_marker[1], ",", words_after_marker[2],"}"))) }
      
      }
      
      stri_word("jose", sentencas, c(1,3) )
      
      #[1] "é um trabalhador" "é um trabalhador" "é um trabalhador" "é um trabalhador"
      
      #Benchmarks
      library(microbenchmark)
      library(stringr)
      
      stringi_positions <- function() {
      
        stri_word <- function(marker, str, words_after_marker) {
      
          stri_sub(str,  cbind(stri_locate_first_coll(str, marker ,strength=1)[, "end"]+1, nchar(str)) ) %>%
          { gsub( "^\\s+|\\s+$", "", stri_extract_first_regex(., paste0("(\\s\\w+){", words_after_marker[1], ",", words_after_marker[2],"}"))) }
      
        }
      
        stri_word("jose", sentencas, c(1,3) )
      
      
      }
      
      stringi_map <- function() {
      
        sentencas %>%
          map(stri_extract_all_words) %>% 
          map(~{
            .x <- flatten_chr(.x)
            map(.x, stri_detect_coll, "jose", ignore.case=TRUE, strength=1L) %>% 
              flatten_lgl() %>%
              which() -> pos
            .x[(pos+1):(pos+1+3)]
          })
      
      
      }
      
      
      semi_stringi <- function() {
      
        sentencas %>% 
          stri_split_coll("jose ", strength=1, simplify = TRUE) %>% 
          .[,2] %>% 
          word(1,3)
      
      
      }
      
      
      microbenchmark(
        stringi_map(),
        semi_stringi(),
        stringi_positions()
      )
      
      # Unit: microseconds
      #                        expr      min       lq      mean    median        uq       max neval
      # stringi_map()       3498.667 3752.886 4059.0339 4038.0925 4214.3480  7365.635   100
      # semi_stringi()      485.543  558.966  805.0216  593.9015  652.7195 15806.567   100
      # stringi_positions()  288.958  325.669  456.9946  344.6180  384.4865 10719.428   100
      

      【讨论】:

        【解决方案3】:

        word() 是一个非常复杂的函数,在 stringi 中没有一个等效的函数。这是实现所需结果的另一种方法:

        library(stringi)
        library(purrr)
        
        sentencas <- c("josé é um trabalhador responsável",
                       "José é um trabalhador responsável",
                       "jose é um trabalhador responsável",
                       "Jose é um trabalhador responsável")
        
        sentencas %>%
          map(stri_extract_all_words) %>% 
          map(~{
            .x <- flatten_chr(.x)
            map(.x, stri_detect_coll, "jose", ignore.case=TRUE, strength=1L) %>% 
              flatten_lgl() %>%
              which() -> pos
            .x[(pos+1):(pos+1+3)]
          })
        ## [[1]]
        ## [1] "é"           "um"          "trabalhador" 
        ## 
        ## [[2]]
        ## [1] "é"           "um"          "trabalhador"
        ## 
        ## [[3]]
        ## [1] "é"           "um"          "trabalhador" 
        ## 
        ## [[4]]
        ## [1] "é"           "um"          "trabalhador" 
        

        【讨论】:

          猜你喜欢
          • 2016-03-16
          • 1970-01-01
          • 1970-01-01
          • 2018-02-28
          • 1970-01-01
          • 2020-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多