从data.table列中删除空格

5
我使用fread来导入非常大的.CSV文件。一些列在文本之后有空格,我需要去掉这些空格。这个过程太耗费时间(几个小时)。
以下代码可以运行,但是system.time命令非常缓慢(在我的计算机上约为12秒,而实际文件要大得多)。
library(data.table)
library(stringr)

# Create example-data
df.1 <- rbind(c("Text1        ", 1, 2), c("Text2        ", 3, 4), c("Text99       ", 5, 6))

colnames(df.1) <- c("Tx", "Nr1", "Nr2")
dt.1 <- data.table(df.1)
for (i in 1:15) {
  dt.1 <- rbind(dt.1, dt.1)
}

# Trim the "Tx"-column
dt.1[, rowid := 1:nrow(dt.1)]
setkey(dt.1, rowid)
system.time( dt.1[, Tx2 :={ str_trim(Tx) }, by=rowid] )
dt.1[, rowid:=NULL]
dt.1[, Tx:=NULL]
setnames(dt.1, "Tx2", "Tx")

有没有更快的方法在data.tables中去除空格?

3个回答

4

如果你有一些重复的值(就像你的例子中一样),你只能操作“Tx”字段的唯一值:

dt.1[, Tx2:=str_trim(Tx),     by=1:nrow(dt.1)]
dt.1[, Tx3:=str_trim(Tx),     by=Tx]

dt.1[, all.equal(Tx2,Tx3)]    # TRUE

与@DWin的回答中使用str_trim相比,使用gsub可以加快速度,无论您是否有重复的“Tx”值。

编辑:正如@DWin指出的那样,首先没有必要按行执行操作,因此不需要对str_trim进行矢量化处理。因此,我已更改我的答案。


2
令人印象深刻。按向量的变化是真正的改进。它也加速了gsub()方法的执行。 - IRTFM

3
system.time( dt.1[, Tx2 :={ str_trim(Tx) }, by=rowid] )
   user  system elapsed 
 19.026   0.105  19.021 

system.time(  dt.1[,  Tx2 := gsub("\\s+$", "", as.character(Tx)), by=rowid]) 
   user  system elapsed 
  4.789   0.053   4.773 

我想知道为什么Hadley的函数这么慢。不管怎样,使用gsub时不需要“by”,对吧? - Frank
我认为这是“by”向量的错误规定。省略它可以节省大量时间,我没有特别的理由认为它应该存在。不过你的“by=Tx”版本甚至更快。 - IRTFM
1
哦,我明白了,str_trim已经向量化了。我只是假设这就是为什么OP在做nrow的事情。 - Frank

1
你可以使用stringr包中的str_trim和dplyr中的mutate。
df %>%
mutate(column1 = str_trim(column1))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接