我有一个列向量Item_A
,包含大约150,000个观察值(1个列变量),另一个列向量Item_B
,包含650个观察值。
如果Item_B
中存在一个单词字符串,Item_A
中将有一个列输出TRUE
。
使用解决方案在Item_B
内的Item_A
中搜索子字符串,并给出一个带有TRUE
或FALSE
的向量,建议使用以下代码:
answer <- grepl(paste(Item_B, collapse = "|"), Item_A)
grepl
与paste
结合使用,但前提是Item_B是较小的向量。我首先尝试在Item_B中仅使用20个观察值,并且它运行良好。
不幸的是,当我尝试使用Error in grepl(paste(Item_B, collapse = "|"), Item_A) :
的652个观测值矢量时,我得到了错误:Item_B
。
您有什么建议使其适用于大向量?
这就是我希望输出的样子:
Item_A Item_B Output_X
cri bat TRUE
sug cri FALSE
cri ird NA TRUE
sure bat NA TRUE
dev dev NA FALSE
batsman NA TRUE
答案 0 :(得分:2)
在我的模拟示例中,使用stringi
的速度比grepl
快50倍:
# sample data
set.seed(47)
a = replicate(150000, sample(letters, size = 6))
b = replicate(600, sample(letters, size = 3))
big_pat = paste(b, collapse = "|")
ans_stringi = stri_detect_regex(a, big_pat)
ans_grepl = grepl(pattern = big_pat, x = a)
identical(ans_stringi, ans_grepl)
# [1] TRUE
# timing comparison
microbenchmark::microbenchmark(
stringi = stri_detect_regex(a, big_pat),
grepl = grepl(pattern = big_pat, x = a),
times = 10L
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# stringi 344.5289 348.7399 404.7191 409.6438 443.1995 477.3867 10
# grepl 17323.6438 18743.7462 19058.1780 19192.0434 20012.5553 20061.1821 10
一种非正则表达式的替代方法是使用fixed
模式并为每个grepl
项目做一个b
。但是我发现这比上面的解决方案要慢得多。
ans_fixed = apply(sapply(Item_B, grepl, x = Item_A, fixed = TRUE), MAR = 1, FUN = any)
使用fixed = TRUE
将使每个grepl
非常快,但是仍然有很多,并且会为length(a)
和length(b)
创建一个大矩阵结果,这可能会消耗大量内存。在我的测试中,grepl
比这里的stri_detect_fixed
快。
如果遇到内存问题,请分块执行,一次说100个Item_B
值。