我的数据集中有一列我要分割的字符串。
df = data.frame(col = c("BrBkRY","BBkRBr","YBRG","RBBk"))
这是我想用来有条件地分割的矢量。
sep = c("Br","Bk","R","Y","B","G")
这应该是最终的样子。我亲手做到了。
df2 = data.frame(col = c("BrBkRY","BBkRBr","YBRG","RBBk"),
col1 = c("Br","B","Y","R"),
col2 = c("Bk","Bk","B","B"),
col3 = c("R","R","R","Bk"),
col4 = c("Y","Br","G",""))
df2
col col1 col2 col3 col4
1 BrBkRY Br Bk R Y
2 BBkRBr B Bk R Br
3 YBRG Y B R G
4 RBBk R B Bk
我在考虑使用正则表达式,但通常情况下,您需要像.
或-
这样的分裂字符。但是根据角色的字符串,我不知道。此外,不想在B,K和B中拆分BkB。但我确实想在Bk和B中将它分开。是否有可以执行此操作的包?
答案 0 :(得分:7)
您可以使用lookahead和lookbehind来使用正则表达式进行拆分。这个表达式表示要分割任何字符和国会大厦字母之间的空格。 (?<=.)
指定一个领先的&#34;任何字符&#34;并且(?=[A-Z])
指定了以下国会大厦。 &#34;任何角色&#34;并且国会大厦实际上并不是比赛的一部分,所以他们不会被吸起来#34;在分裂。
> lst <- strsplit(as.character(df$col), '(?<=.)(?=[A-Z])', perl=TRUE)
> lst
[[1]]
[1] "Br" "Bk" "R" "Y"
[[2]]
[1] "B" "Bk" "R" "Br"
[[3]]
[1] "Y" "B" "R" "G"
[[4]]
[1] "R" "B" "Bk"
然后可以构建列,例如与akrun的答案完全相同:
dfN <- cbind(df[1], do.call(rbind, lapply(lst, `length<-`, max(lengths(lst)))))
colnames(dfN)[-1] <- paste0("col", colnames(dfN)[-1])
答案 1 :(得分:2)
我们可以使用str_extract_all
在填充NA后提取list
中的组件,然后rbind
list
个元素,以生成length
list
1}}元素相同,cbind
与原始数据集
library(stringr)
lst <- str_extract_all(df$col, paste(sep, collapse="|"))
dfN <- cbind(df[1], do.call(rbind, lapply(lst, `length<-`, max(lengths(lst)))))
colnames(dfN)[-1] <- paste0("col", colnames(dfN)[-1])
dfN
# col col1 col2 col3 col4
#1 BrBkRY Br Bk R Y
#2 BBkRBr B Bk R Br
#3 YBRG Y B R G
#4 RBBk R B Bk <NA>
或base R
选项与read.csv
和gsub
cbind(df[1], read.csv(text=sub("^,", "", gsub(paste0("(?=(",
paste(sep, collapse="|"), "))"), ",", df$col, perl = TRUE)),
header=FALSE, col.names = paste0("col", 1:4), fill = TRUE))
# col col1 col2 col3 col4
#1 BrBkRY Br Bk R Y
#2 BBkRBr B Bk R Br
#3 YBRG Y B R G
#4 RBBk R B Bk