在 data.table 中拆分字符串并转换为长格式的快速方法

Posted

技术标签:

【中文标题】在 data.table 中拆分字符串并转换为长格式的快速方法【英文标题】:Fast way to split string and convert to long format in data.table 【发布时间】:2014-05-05 20:54:03 【问题描述】:

我做以下事情

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 不是正确的做法?

【问题讨论】:

请发布最小样本数据 您当前的“string_column”变量中有重复的值。应该是这样吗? 不,抱歉,需要唯一的行(去掉 replace = TRUE ) 【参考方案1】:

如果您放弃使用“stringr”中的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 

这是否会使您的处理时间从 1 小时缩短到 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() 得到的答案不同,但那是因为您在“string_column”中有重复的值。如果您添加一个“id”列并执行相同操作,您将获得相同的结果。

【讨论】:

谢谢,在我的情况下,我的速度提高了十倍 - 是 - 3660s,现在 - 370s

以上是关于在 data.table 中拆分字符串并转换为长格式的快速方法的主要内容,如果未能解决你的问题,请参考以下文章

通过多个步骤将宽数据集转换为长数据集

将字符串转换为列表并嵌套在data.table中

R语言将dataframe宽表转化为长表实战:使用data.table使用tidyr包gather函数使用reshape2包

当列名是字符串时,转换为长并制作频率表,R

字符串拆分data.table列生成NA

如何将字符串日期转换为长毫秒