在R中使用动态(变量)字符串作为正则表达式模式
我有一个data.table DT_words(大维度):在R中使用动态(变量)字符串作为正则表达式模式,r,regex,dynamic,nested,data.table,R,Regex,Dynamic,Nested,Data.table,我有一个data.table DT_words(大维度): 编辑:我编辑了DT_字符串以包含更多的单词匹配示例。我只对匹配整个单词感兴趣,因此必须以某种方式包含regex语法。这里有一个使用tidyverse包套件的解决方案 library(stringr) library(purrr) DT_words$word_count <- map_int(paste0("\\b", DT_words$word,"\\b"), ~ str_count(DT_strings$string,
编辑:我编辑了DT_字符串以包含更多的单词匹配示例。我只对匹配整个单词感兴趣,因此必须以某种方式包含regex语法。这里有一个使用
tidyverse
包套件的解决方案
library(stringr)
library(purrr)
DT_words$word_count <- map_int(paste0("\\b", DT_words$word,"\\b"),
~ str_count(DT_strings$string, .x) %>% sum)
假设你所说的字符串和单词来自自然语言,我建议下面的BaseR解决方案可能运行得更快。关键是你必须将字符串中的不同单词分开,但是很容易将“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
s如果您的单词确实只是用空格分隔,我会将它们拆分为列,转换为长格式,然后运行二进制连接,并与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+”)
,这可能会更慢。什么是as.character
,如果要转换DT_单词
,您应该在答案中包含它。FWIW您可能不需要进行此转换。正如OP特别提到的,DT_words
具有很大的维度,效率对于他的案例可能很重要:)是的,的确。。。。将有超过20000个DT_单词和近500000个DT_字符串条目。我希望找到一个data.table+apply解决方案管理,我不知道data.table-但是apply
(可能是map
)被认为是“循环隐藏”而不是“循环避免”。我认为没有办法避免R中的循环-使用vapply
而不是map\u int
,可以获得相同的基本效果-这可能会更快。@MelissaKey您的解决方案不起作用,因为它还将单词计算为另一个单词的一部分。用DT_弦试试哇。做这件事真是太好了。非常感谢。
> DT_words
word word_count
1: word1 2
2: word2 3
3: word3 1
4: word4 0
library(stringr)
library(purrr)
DT_words$word_count <- map_int(paste0("\\b", DT_words$word,"\\b"),
~ str_count(DT_strings$string, .x) %>% sum)
DT_words$word_count <- vapply(paste0("\\b", DT_words$word, "\\b"), function(x) {
sum(str_count(DT_strings$string, x))
}, 0)
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
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