我做以下
library(data.table)
library(stringr)
dt <- data.table(string_column = paste(sample(c(letters, " "), 500000, replace = TRUE)
, sample(c(letters, " "), 500000, replace = TRUE)
, sample(1:500000)
, sep = " "), key = "string_column")
split_res <- dt[, list(name = unlist(str_split(string_column, '\\s+'))), by = string_column]
对于实际数据,需要大约。 1小时处理dt
(10M行)并创建split_res
(18M行)
出于好奇 - 有没有办法加快进程?也许unlist + str_split
不是正确的做法吗?
答案 0 :(得分:11)
如果您只是使用来自&#34; stringr&#34;的str_split()
,您将获得更大的加速。并使用strsplit()
。
fun1 <- function() dt[, list(name = unlist(str_split(string_column, '\\s+'))), by = string_column]
fun2 <- function() dt[, list(name = unlist(strsplit(string_column, '\\s+'))), by = string_column]
system.time(fun1())
# user system elapsed
# 172.41 0.05 172.82
system.time(fun2())
# user system elapsed
# 11.22 0.01 11.23
这是否会使您的处理时间从一小时缩短到4分钟,我不确定。但至少你不必记得在你的函数名称中加入那些令人讨厌的下划线: - )
如果您可以拆分固定搜索模式,则可以使用fixed = TRUE
参数,这将为您提供另一个显着的速度提升。
要考虑的另一件事是手动完成这个过程:
x <- strsplit(dt$string_column, "\\s+")
DT <- dt[rep(sequence(nrow(dt)), vapply(x, length, 1L))]
DT[, name := unlist(x, use.names = FALSE)]
DT
使用您的样本数据:
fun4 <- function() {
x <- strsplit(dt$string_column, "\\s+")
DT <- dt[rep(sequence(nrow(dt)), vapply(x, length, 1L))]
DT[, name := unlist(x, use.names = FALSE)]
DT
}
# user system elapsed
# 1.79 0.01 1.82
然而,答案与fun2()
的答案不同,但那是因为你在&#34; string_column&#34;中有重复的值。如果你添加一个&#34; id&#34;列并做同样的事情,你会得到相同的结果。