RIn*_*atM 7 substring r data-manipulation data.table
我做了以下事情
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]
Run Code Online (Sandbox Code Playgroud)
对于真实数据,它需要大约.1小时处理dt
(10M行)并创建split_res
(18M行)出于好奇 - 有没有办法加快进程?也许unlist + str_split
这不是正确的方法吗?
A5C*_*2T1 11
如果您只是使用str_split()
"stringr"并且只是使用,那么您将获得大幅加速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
Run Code Online (Sandbox Code Playgroud)
这是否会使您的处理时间从一小时缩短到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
Run Code Online (Sandbox Code Playgroud)
使用您的示例数据:
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
Run Code Online (Sandbox Code Playgroud)
但是,答案与我所得到的不一样fun2()
,但那是因为你在"string_column"中有重复的值.如果添加"id"列并执行相同操作,则会得到相同的结果.