Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在R中使用动态(变量)字符串作为正则表达式模式_R_Regex_Dynamic_Nested_Data.table - Fatal编程技术网

在R中使用动态(变量)字符串作为正则表达式模式

在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,

我有一个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, .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