将dataframestring列拆分为多个不同的列
我试图完成的是将一个列分成多个列。 我宁愿第一列包含“F”,第二列“美国”,第三“CA6”或“DL”,第四个是“Z13”或“U13”等。我整个df遵循相同的模式X.XX.XXXX.XXX或X.XX.XXX.XXX或X.XX.XX.XXX我知道第三列是我的问题在于哪里,因为长度不同。 我过去只使用了substr,我可以在这里使用一些if语句,但是想学习如何使用stringr包和POSIX来做到这一点(除非有更好的select)。 先谢谢你。
这是我的df:
c("F.US.CLE.V13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.DL.U13", "F.US.DL.U13", "F.US.DL.U13", "F.US.DL.Z13", "F.US.DL.Z13" )
一个非常直接的方法就是在你的angular色vector上使用read.table
:
> read.table(text = text, sep = ".", colClasses = "character") V1 V2 V3 V4 1 F US CLE V13 2 F US CA6 U13 3 F US CA6 U13 4 F US CA6 U13 5 F US CA6 U13 6 F US CA6 U13 7 F US CA6 U13 8 F US CA6 U13 9 F US DL U13 10 F US DL U13 11 F US DL U13 12 F US DL Z13 13 F US DL Z13
colClasses
需要指定,否则F
被转换为FALSE
(这是我需要修复“splitstackshape”,否则我会build议:))
更新(>一年以后)…
或者,您可以使用我的cSplit
函数 ,如下所示:
cSplit(as.data.table(text), "text", ".") # text_1 text_2 text_3 text_4 # 1: F US CLE V13 # 2: F US CA6 U13 # 3: F US CA6 U13 # 4: F US CA6 U13 # 5: F US CA6 U13 # 6: F US CA6 U13 # 7: F US CA6 U13 # 8: F US CA6 U13 # 9: F US DL U13 # 10: F US DL U13 # 11: F US DL U13 # 12: F US DL Z13 # 13: F US DL Z13
或者, separate
“tidyr” separate
,就像这样:
library(dplyr) library(tidyr) as.data.frame(text) %>% separate(text, into = paste("V", 1:4, sep = "_")) # V_1 V_2 V_3 V_4 # 1 F US CLE V13 # 2 F US CA6 U13 # 3 F US CA6 U13 # 4 F US CA6 U13 # 5 F US CA6 U13 # 6 F US CA6 U13 # 7 F US CA6 U13 # 8 F US CA6 U13 # 9 F US DL U13 # 10 F US DL U13 # 11 F US DL U13 # 12 F US DL Z13 # 13 F US DL Z13
这是你正在尝试做什么?
# Our data text <- c("F.US.CLE.V13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.DL.U13", "F.US.DL.U13", "F.US.DL.U13", "F.US.DL.Z13", "F.US.DL.Z13" ) # Split into individual elements by the '.' character # Remember to escape it, because '.' by itself matches any single character elems <- unlist( strsplit( text , "\\." ) ) # We know the dataframe should have 4 columns, so make a matrix m <- matrix( elems , ncol = 4 , byrow = TRUE ) # Coerce to data.frame - head() is just to illustrate the top portion head( as.data.frame( m ) ) # V1 V2 V3 V4 #1 F US CLE V13 #2 F US CA6 U13 #3 F US CA6 U13 #4 F US CA6 U13 #5 F US CA6 U13 #6 F US CA6 U13
通过unlist
和matrix
的方式似乎有点复杂,并且需要硬编码元素的数量(这实际上是一个非常大的禁止行为。当然,你可以绕过硬编码这个数字,并在运行时确定它)
我会走一条不同的路线,并直接从strsplit
返回的列表中构build一个数据框架。 对我而言,这在概念上更简单。 实质上有两种方法:
-
as.data.frame
– 但由于列表正好是错误的方式(我们有一个行列表而不是列列表),我们必须转置结果。 我们也清除rownames
因为它们默认是丑陋的(但是这是不必要的!):`rownames<-`(t(as.data.frame(strsplit(text, '\\.'))), NULL)
-
或者,使用
rbind
从行列表构造一个数据框。 我们使用do.call
将所有行作为单独的参数调用rbind
:do.call(rbind, strsplit(text, '\\.'))
两种方法都可以得到相同的结果
[,1] [,2] [,3] [,4] [1,] "F" "US" "CLE" "V13" [2,] "F" "US" "CA6" "U13" [3,] "F" "US" "CA6" "U13" [4,] "F" "US" "CA6" "U13" [5,] "F" "US" "CA6" "U13" [6,] "F" "US" "CA6" "U13" …
显然,第二种方法比第一种简单得多。