2017-01-28 37 views
3

分割したい文字列があるデータセットに列があります。文字列に基づいて文字列を分割する

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、B、BでBkBを分割したくないですが、BkとBで分けたいと思います。これを行うパッケージはありますか?

答えて

7

lookaheadとlookbehindを使用して、正規表現で分割を実行できます。この式は、任意の文字と首都文字の間のスペースを分割すると言います。 (?<=.)は先行する「任意の文字」を指定し、(?=[A-Z])は次の議事堂を指定します。 「任意のキャラクター」とキャピトルは実際に試合の一部ではないので、スプリットで「吸い上げ」られません。

> 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]) 
2

我々は同じlengthlistの要素、および元のデータセットと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> 

を作るためにパディングNA後、その後rbindlist要素、listで成分を抽出するためにstr_extract_allを使用することができますか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  
0123です。
関連する問題