根据字符拆分R中的字符串

时间:2017-01-28 17:13:34

标签: r string split

我的数据集中有一列我要分割的字符串。

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中将它分开。是否有可以执行此操作的包?

2 个答案:

答案 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.csvgsub

一起使用
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