我有一个脚本,可以将CSV文件中的数据读入data.table,然后将一列中的文本拆分为几列.我目前正在使用lapplystrsplit函数来实现这一点.下面是一个例子:

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被拆分为两个新的列PXPY,分别位于"u"字符上.

Even though this works just fine, I was wondering if there is a better (more efficient) way to do this using data.table. My real datasets have >=10M+ rows, so time/memory efficiency becomes really important.


更新:

按照@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倍的时间.

推荐答案

Update:从1.9.6版(从2015年9月起在CRAN上)开始,我们可以使用函数tstrsplit()直接(以更高效的方式)获得结果:

require(data.table) ## v1.9.6+
dt[, c("PX", "PY") := tstrsplit(PREFIX, "_", fixed=TRUE)]
#    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

tstrsplit()基本上是transpose(strsplit())的包装器,其中transpose()函数(也是最近实现的)转置列表.有关示例,请参见?tstrsplit()?transpose().

旧答案见历史.

R相关问答推荐

R:对于没有数据的缓冲区,加权平均值为0

使用scale_x_continuous复制ggplot 2中的离散x轴

在数据表中呈现数学符号

变量计算按R中的行更改

从多个前置日期中获取最长日期

具有多个依赖变量/LHS的逻辑模型

如何求解arg必须为NULL或deSolve包的ode函数中的字符向量错误

如何使用`ggplot2::geom_segment()`或`ggspatial::geom_spatial_segment()`来处理不在格林威治中心的sf对象?

derrr mutate case_when grepl不能在R中正确返回值

如何编辑gMarginal背景以匹配绘图背景?

提取第一个下划线和最后一个下划线之间的任何内容,例外情况除外

如何写商,水平线,在一个单元格的表在R

在ggplot2的框图中绘制所有级别的系数

在数据帧列表上绘制GGPUP

在另一个包中设置断点&S R函数

调换行/列并将第一行(原始数据帧的第一列)提升为标题的Tidyr类似功能?

在ggploy中创建GeV分布时出错

是否从列中删除★符号?

在shiny 表格中输入的文本在第一次后未更新

通过匹配另一个表(查找表)中的列值来填充数据表,并在另一个变量上进行内插