我的数据是这样的
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我尝试制定规则。每个字符串首先停留在同一列上。如果是分开的;然后它移动到下一列但保持在同一行
答案 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)
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
中使用ifelse
或sapply
,这会增加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>