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

在r中使用动态(变量)字符串作为regex模式

  •  2
  • Ankhnesmerira  · 技术社区  · 7 年前

    我有一个数据表dt_字(大尺寸):

    DT_words <- data.table(word = c('word1', 'word2', 'word3','word4'))
    

    我还有另一个data.table dt_字符串,其中包含一个包含大量字符串的列

    DT_strings <- data.table(string = c('string1 made of word1', 'string2 made of word2 and word2 and word3 and word1ly', 'string3 made of word1 and word2'))
    

    对于dt_-word中的每个单词,我想计算dt_-string中所有字符串中出现的总数,并将该值保存为dt_-word中的一列。 我用它做环,看起来很难看。

    我试过使用laply和mapply,但是没有用,因为函数需要一个内部输入。

    这是for循环的单词(但它需要很长时间,而且很难看)

    require(stringr)
    
    for (i in 1:nrow(DT_words))
    {
       DT_words$word_count[i] <-  sum(str_count(DT_strings$string, 
                                      paste0(c("\\b("),paste(DT_words[i, .(word)]),c(")\\b"))))
    }
    

    我知道格式更像是一个data.frame,但是因为我使用的是循环,所以这并不重要,是吗? 不管怎样,我想知道是否可以在data.table中使用apply来消除这种丑陋。

    期望输出为:

    > DT_words
        word word_count
    1: word1          2
    2: word2          3
    3: word3          1
    4: word4          0
    

    编辑:我编辑了dt_字符串以包含更多匹配单词的示例。我只对匹配整个单词感兴趣,因此必须以某种方式包含regex语法。

    3 回复  |  直到 7 年前
        1
  •  1
  •   David Arenburg Ulrik    7 年前

    如果您的单词确实被一个空格分隔,我会将它们拆分为列,转换为长格式,然后运行结合 by = .EACHI 例如,使用您的数据:

    library(data.table)
    library(magrittr)                       
    DT_strings[, tstrsplit(string, " ", fixed = TRUE)] %>% 
      melt(., measure.vars = names(.), na.rm = TRUE) %>%
      .[DT_words, on = .(value = word), .N, by = .EACHI]
    #    value N
    # 1: word1 2
    # 2: word2 3
    # 3: word3 1
    # 4: word4 0
    

    附笔。

    我用过 fixed = TRUE 对于速度,正如我假设的,每个词之间总是有一个空格。如果空间不同,您需要使用 tstrsplit(string, "\\s+") 相反,这可能会更慢。

        2
  •  0
  •   Nicolas2    7 年前

    假设您所称的字符串和单词来自自然语言,我建议使用以下可能运行得更快的基本r解决方案。重点是你必须在字符串中分隔不同的单词,但是很容易将“strsplit”与其他分隔符相适应。

    s <- c('string1 made of word1', 'string2 made of word2 and word2 and word3', 'string3 made of word1 and word2')
    w <- c('word1', 'word2', 'word3','word4')
    
    z <- as.data.frame(table(unlist(strsplit(s,' '))))
    z[z$Var1 %in% w,]
    
    #   Var1 Freq
    #7 word1    2
    #8 word2    3
    #9 word3    1
    
        3
  •  0
  •   Melissa Key    7 年前

    下面是一个使用 tidyverse 套装。

    library(stringr)
    library(purrr)
    
    DT_words$word_count <- map_int(paste0("\\b", DT_words$word,"\\b"),
       ~ str_count(DT_strings$string, .x) %>% sum)
    

    不使用的替代方案 purrr :

    DT_words$word_count <- vapply(paste0("\\b", DT_words$word, "\\b"), function(x) {
      sum(str_count(DT_strings$string, x))
    }, 0)