我有一个很长的字符向量(例如" Hello World"等),1.7M行,我需要使用两个向量之间的映射替换它们中的单词,并将结果保存在同一个向量。这是一个简单的例子:
library(qdap)
line = c("one", "two one", "four phones")
e = c("one", "two")
r = c("ONE", "TWO")
line = mgsub(e,r,line)
结果:
[1] "ONE" "TWO ONE" "four phONEs"
正如您所看到的,e[j]
的每个实例都会被r[j]
替换为r[j]
。
它适用于相对较小的线路和#34;和e->r
词汇长度,但当我在length(line) = 1700000
和length(e) = 750
上运行时,我达到了总分配的内存:
Reached total allocation of 7851Mb: see help(memory.size)
任何想法如何避免它?
答案 0 :(得分:2)
stringi 包为许多字符串操作提供快速一致的工具:
stri_replace_all_regex(line, paste0("\\b", e, "\\b"), r, vectorize_all = FALSE)
与其他方法一样快速地接近(不同的分数)并且更直接。
答案 1 :(得分:1)
更新问题(对于管理员:如果它没有得到单独的答案 - 请将其与原始答案合并)。与简单的for循环相比,mgsub
运行得如此之快的原因是默认情况下mgsub
参数fixed = TRUE
,而gsub
默认为FALSE
!我刚发现它。
我想再次澄清一点,fixed=TRUE
不适合我,因为我不想替换caps
中的capsule
,而只取代caps
这个词\\b
}。即我被迫将fixed=TRUE
粘贴到模式中。以下是我的代码中的三个代码段(我在gsub
中测试#This is with mgsub. Now with fixed = FALSE!!
i = mgsub(paste("\\b",orig,"\\b",sep=""),change,i,fixed=FALSE)
#This is with a for loop. fixed=TRUE in one of lines is for test purposes only. Do not use
for(k in seq_along(orig)) {
i = gsub(paste("\\b",orig[k],"\\b",sep=""),change[k],i)
#i = gsub(orig[k],change[k],i,fixed=TRUE)
}
只是为了查看时差,而不是使用它。)
N | mgsub, fixed=F | gsub, fixed=F | gsub, fixed=T
--------------------------------------------------------------
100k | 41sec, M > 2.3GB | 37sec, M > 0.9GB | 9sec, M > 0.8GB
200k | 99sec, M > 4GB | 74sec, M > 1.1GB | 18sec, M > 1.3GB
300k | 132sec, M > 5.6GB| 112sec, M > 2.6GB| 28sec, M > 1.6GB
+ disk involved
以下是不同数量输入数据的所有三种情况的时间和内存使用情况:
fixed
因此,我得出结论,对于FALSE
必须mgsub
时的申请,使用for
没有优势。实际上,{{1}}循环更快,不会导致内存溢出!
感谢所有参与者。我希望我可以给评论者提供学分,但我不知道如何在#34;评论"
答案 2 :(得分:1)
我相信你可以使用fixed = TRUE
。
你似乎关心它听起来像的空间......所以只需在你正在使用的所有3个矢量的末尾添加空格。要将整个序列从## Start
运行到## Finish
(大致相当于您的数据的大小),需要在170万字符串上Time difference of 2.906395 secs
。大部分时间都是在剥离额外空间的最后时间。
## Recreate data
line <- c("one", "two one", "four phones", "and a capsule", "But here's a caps key")
e <- c("one", "two", "caps")
r <- c("ONE", "TWO", "CAPS")
line <- rep(line, 1700000/length(line))
## Start
line2 <- paste0(" ", line, " ")
e2 <- paste0(" ", e, " ")
r2 <- paste0(" ", r, " ")
for (i in seq_along(e2)) {
line2 <- gsub(e2[i], r2[i], line2, fixed=TRUE)
}
gsub("^\\s|\\s$", "", line2, perl=TRUE)
## Finish
此处 qdap &#39; mgsub
没用。该软件包专为更小的数据而设计。此外,fixed = TRUE
是一个合理的默认值,因为它更快。添加包的重点是通过重新配置可用工具来改进工作流程(有时是字段/任务特定)。 mgsub
函数也有一些错误处理和其他有助于分析使函数占用内存的转录本的细节。通常需要在安全+语法糖 与 速度之间进行权衡。
请注意,仅仅因为以相似的方式命名2个函数不应该暗示任何东西,特别是如果它们在包中添加。甚至基本R中的函数也有不同的命名和行为默认值(查看apply
函数族;这个问题不太理想,但却是R的历史演变的一部分。作为用户,您有责任阅读文档而不做出假设。