【发布时间】:2013-08-11 20:24:03
【问题描述】:
我有一个脚本,它将 CSV 文件中的数据读入 data.table,然后将一列中的文本拆分为几个新列。我目前正在使用lapply 和strsplit 函数来执行此操作。这是一个例子:
library("data.table")
df = data.table(PREFIX = c("A_B","A_C","A_D","B_A","B_C","B_D"),
VALUE = 1:6)
dt = as.data.table(df)
# split PREFIX into new columns
dt$PX = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 1))
dt$PY = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 2))
dt
# PREFIX VALUE PX PY
# 1: A_B 1 A B
# 2: A_C 2 A C
# 3: A_D 3 A D
# 4: B_A 4 B A
# 5: B_C 5 B C
# 6: B_D 6 B D
在上面的示例中,PREFIX 列在“_”字符上被拆分为两个新列 PX 和 PY。
尽管这工作得很好,但我想知道是否有更好(更有效)的方法来使用data.table。我的真实数据集有 >=10M+ 行,因此时间/内存效率变得非常重要。
更新:
按照@Frank 的建议,我创建了一个更大的测试用例并使用了建议的命令,但stringr::str_split_fixed 比原来的方法花费的时间要长很多。
library("data.table")
library("stringr")
system.time ({
df = data.table(PREFIX = rep(c("A_B","A_C","A_D","B_A","B_C","B_D"), 1000000),
VALUE = rep(1:6, 1000000))
dt = data.table(df)
})
# user system elapsed
# 0.682 0.075 0.758
system.time({ dt[, c("PX","PY") := data.table(str_split_fixed(PREFIX,"_",2))] })
# user system elapsed
# 738.283 3.103 741.674
rm(dt)
system.time ( {
df = data.table(PREFIX = rep(c("A_B","A_C","A_D","B_A","B_C","B_D"), 1000000),
VALUE = rep(1:6, 1000000) )
dt = as.data.table(df)
})
# user system elapsed
# 0.123 0.000 0.123
# split PREFIX into new columns
system.time ({
dt$PX = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 1))
dt$PY = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 2))
})
# user system elapsed
# 33.185 0.000 33.191
所以str_split_fixed 方法需要大约 20 倍的时间。
【问题讨论】:
-
我认为先在 data.table 之外进行操作可能会更好。如果您使用
stringr包,这是命令:str_split_fixed(PREFIX,"_",2)。我没有回答,因为我还没有测试加速......或者,一步:dt[,c("PX","PY"):=data.table(str_split_fixed(PREFIX,"_",2))]
标签: r data.table