将一列字符串拆分为几列[重复]

Posted

技术标签:

【中文标题】将一列字符串拆分为几列[重复]【英文标题】:split a column of string in several columns [duplicate] 【发布时间】:2016-03-24 04:47:13 【问题描述】:

我有数据框

df=data.frame(x=rnorm(8),y=runif(8),longstring=c("foo_100_Case1","foo_125_Case1","bar_100_Case1","bar_125_Case1","foo_100_Case2","foo_125_Case2","bar_100_Case2","bar_125_Case2"),stringsAsFactors = F)

我需要用分隔符“_”将最后一列分成三列。我一直在做以下事情:

a=matrix(unlist(strsplit(df$longstring,"_",fixed=T)),8,3,byrow = T)
df$type=a[,1]
df$point=a[,2]
df$case=a[,3]

但我想知道是否有更简单的方法:strsplitunlist的组合特别尴尬,并且不会使代码变得非常可读。

【问题讨论】:

tidyr 包中的函数separate 就是专门为此编写的。 【参考方案1】:

这里有更多选项可供尝试:

我的“splitstackshape”包就是为这类东西设计的……

library(splitstackshape)
cSplit(df, "longstring", "_")
#              x         y longstring_1 longstring_2 longstring_3
# 1: -1.41524742 0.2123978          foo          100        Case1
# 2: -1.09240237 0.3899935          foo          125        Case1
# 3:  0.39675025 0.2162463          bar          100        Case1
# 4: -1.14996728 0.7608128          bar          125        Case1
# 5: -0.07657172 0.6878348          foo          100        Case2
# 6:  0.29549599 0.2216566          foo          125        Case2
# 7:  1.78622612 0.1496666          bar          100        Case2
# 8: -0.11749579 0.9255409          bar          125        Case2

“data.table”包为我们带来了快速的tstrsplit函数...

library(data.table)
as.data.table(df)[
  , paste0("V", 1:3) := tstrsplit(longstring, "_")][
    , longstring := NULL][]

如果您有时间并想等待read.table 完成工作...

cbind(df[1:2], read.table(text = df$longstring, sep = "_"))

如果您需要其他快速的东西...

library(iotools)
cbind(df[1:2], mstrsplit(df$longstring, sep = "_"))

【讨论】:

【参考方案2】:

你可以试试,

cbind(df[-3], data.frame(do.call('rbind', strsplit(df$longstring,'_'))))

#    x               y   X1  X2    X3
#1 -0.5522704 0.9998266 foo 100 Case1
#2  1.1907351 0.8979460 foo 125 Case1
#3  0.6005691 0.4301610 bar 100 Case1
#4 -1.0698081 0.9626781 bar 125 Case1
#5 -0.8526932 0.9634738 foo 100 Case2
#6  0.0100209 0.2968137 foo 125 Case2
#7 -1.5051358 0.7012956 bar 100 Case2
#8  1.0892584 0.4655736 bar 125 Case2

do.call 函数允许您调用任何 R 函数,而不是一一发送参数,您可以使用列表来保存参数。更多信息?do.calldo.call 仅返回 X1X2X3 列,为了获取您的原始数据框,我使用 cbind 绑定原始列。如您所知,strsplit 将字符串拆分为 _


或者正如@joran 提到的,你可以使用separate from tidyr package like

library(tidyr)
separate(df, longstring, c("X1", "X2", "X3"), sep="_")

#    x               y   X1  X2    X3
#1 -0.5522704 0.9998266 foo 100 Case1
#2  1.1907351 0.8979460 foo 125 Case1
#3  0.6005691 0.4301610 bar 100 Case1
#4 -1.0698081 0.9626781 bar 125 Case1
#5 -0.8526932 0.9634738 foo 100 Case2
#6  0.0100209 0.2968137 foo 125 Case2
#7 -1.5051358 0.7012956 bar 100 Case2
#8  1.0892584 0.4655736 bar 125 Case2

【讨论】:

绝对比我的更具可读性,我喜欢你放弃df$longstring。不过,您能解释一下您的代码吗? do.call 是什么?为什么你需要cbindrbind?为什么在你的代码中需要as.character,而在我的代码中我可以直接写strsplit(df$longstring...) 好的,我最喜欢tidyr 语法。通常我不喜欢安装包来完成可以在基础 R 中完成的事情,但我真的很喜欢 tidyr 允许我一次性分离和重命名列的事实。而且语法更具可读性! @DeltaIV 你是对的,tidyr 更具可读性,而且strsplit 中也不需要as.character,因此更新了

以上是关于将一列字符串拆分为几列[重复]的主要内容,如果未能解决你的问题,请参考以下文章

根据多个条件将一列拆分为几列并分组

Pandas Dataframe:如何将一列拆分为多个单热编码列[重复]

Matlab中tabel如何按照日期列拆分

将一列中的字符串拆分为表维护 ID 的多个分隔符

将一列拆分为多行

使用 r 将一列拆分为两列 [重复]