基于分号将字符串拆分为不同的列

时间:2016-06-29 19:12:21

标签: r

我的数据是这样的

dff<- structure(c(7L, 6L, 5L, 4L, 3L, 2L, 1L, 1L, 1L), .Label = c("", 
"P42356;Q8N8J0;A4QPH2", "P67809;Q9Y2T7", "Q08554", "Q13835", 
"Q5T749", "Q9NZT1"), class = "factor")

我尝试拆分我的字符串并将它们放在不同的列中

例如输出应该如下所示

 A       B        C        
Q9NZT1
Q5T749
Q13835
Q08554  
P67809   Q9Y2T7 
P42356   Q8N8J0   A4QPH2

我尝试使用strsplit,但它没有用。

unlist(strsplit(dff, ";", fixed = TRUE))

感谢@thepule我尝试制定规则。每个字符串首先停留在同一列上。如果是分开的;然后它移动到下一列但保持在同一行

7 个答案:

答案 0 :(得分:3)

我喜欢这些粗糙类型数据的 splitstackshape 包:

onResume

答案 1 :(得分:3)

您可以从矢量构建数据框,然后将其分开:

tidyr::separate(data.frame(text = dff), text, into = c("A", "B", "C"), sep = ";", fill = "right", extra = "drop")
       A      B      C
1 Q9NZT1   <NA>   <NA>
2 Q5T749   <NA>   <NA>
3 Q13835   <NA>   <NA>
4 Q08554   <NA>   <NA>
5 P67809 Q9Y2T7   <NA>
6 P42356 Q8N8J0 A4QPH2

数据

c("Q9NZT1", "Q5T749", "Q13835", "Q08554", "P67809;Q9Y2T7", "P42356;Q8N8J0;A4QPH2"
)

答案 2 :(得分:1)

啊,看起来我是唯一一个使用R的基本功能的人。

x <- strsplit(as.character(dff), ";")
l <- lengths(x)  ## R 3.3.0 onward
m <- max(l)
x <- t(sapply(x[as.logical(l)], function(a) c(a, rep("",m-length(a)))))

x
#      [,1]     [,2]     [,3]    
# [1,] "Q9NZT1" ""       ""      
# [2,] "Q5T749" ""       ""      
# [3,] "Q13835" ""       ""      
# [4,] "Q08554" ""       ""      
# [5,] "P67809" "Q9Y2T7" ""      
# [6,] "P42356" "Q8N8J0" "A4QPH2"

如果您想要数据框,只需as.data.frame(x)将此矩阵强制转换为数据框:

#       V1     V2     V3
# 1 Q9NZT1              
# 2 Q5T749              
# 3 Q13835              
# 4 Q08554              
# 5 P67809 Q9Y2T7       
# 6 P42356 Q8N8J0 A4QPH2

<强>后续

关于您以后的请求,我们可以这样做:

x <- strsplit(as.character(dff), ";")
ind <- as.logical(l <- lengths(x))  ## R 3.3.0 onward
m <- max(l <- l[ind])
x <- t(sapply(x[ind], function(a) c(paste(a,1:length(a),sep="_"), rep("",m-length(a)))))
ind <- l==1L; x[ind,1] <- gsub("_1","",x[ind,1])

#      [,1]       [,2]       [,3]      
# [1,] "Q9NZT1"   ""         ""        
# [2,] "Q5T749"   ""         ""        
# [3,] "Q13835"   ""         ""        
# [4,] "Q08554"   ""         ""        
# [5,] "P67809_1" "Q9Y2T7_2" ""        
# [6,] "P42356_1" "Q8N8J0_2" "A4QPH2_3"

如果您想要数据框,请再次使用as.data.frame。我最后使用了一个gsub,因为我不想在if...else中使用ifelsesapply,这会增加R解释开销。

答案 3 :(得分:1)

我还有另一种非常残酷的解决方案:

library(dplyr)
library(stringr)

list <- lapply(str_split(dff, ";"), function(x) {
        if(x[1] != "") data.frame(lapply(x, data.frame), stringsAsFactors = F)
})

list <- list[!sapply(list, is.null)]
final <- bind_rows(list)

final
Source: local data frame [6 x 3]

  X..i.. X..i...1 X..i...2
   (chr)    (chr)   (fctr)
1 Q9NZT1       NA       NA
2 Q5T749       NA       NA
3 Q13835       NA       NA
4 Q08554       NA       NA
5 P67809   Q9Y2T7       NA
6 P42356   Q8N8J0   A4QPH2

答案 4 :(得分:1)

你正朝着正确的方向前进(如果它不是因素),strsplit期望字符向量,当生成列表时,你需要的只是rbind它们。

***With your input data***
# Not sure why you want them as factors

这仍然有效......

my_list <-  strsplit(as.character(dff), ';')

require(plyr)
res<- ldply(my_list ,rbind)

输出

   1      2      3
1 Q9NZT1   <NA>   <NA>
2 Q5T749   <NA>   <NA>
3 Q13835   <NA>   <NA>
4 Q08554   <NA>   <NA>
5 P67809 Q9Y2T7   <NA>
6 P42356 Q8N8J0 A4QPH2

答案 5 :(得分:1)

library(splitstackshape)
res <- cSplit(data.frame(dff), "dff", sep=";", drop=TRUE)

这就是你所需要的一切。但如果NA吓到你了:

res[] <- lapply(res, as.character)
res[is.na(res)] <- ''

答案 6 :(得分:1)

你也可以使用 str_split 对字符串和模式进行矢量化,因此,你不需要将它转换为字符

library(plyr)
library(stringr)
x <- str_split(dff, ";")
res<- ldply(x ,bind)
#       1      2      3
#1 Q9NZT1   <NA>   <NA>
#2 Q5T749   <NA>   <NA>
#3 Q13835   <NA>   <NA>
#4 Q08554   <NA>   <NA>
#5 P67809 Q9Y2T7   <NA>
#6 P42356 Q8N8J0 A4QPH2
#7          <NA>   <NA>
#8          <NA>   <NA>
#9          <NA>   <NA>