2017-08-11 3 views
2

に基づいて複数の列に1列を分割するように私は、2つの列を持つデータフレームを持っている:私は2番目の列内のマーカー文字に基づいて、複数の列に2つ目の列を分割したいマーカー文字

**+-----+-------+ 
| V1 | V2  | 
+-----+---------+ 
| 1 | a,b,c | 
| 2 | a,c  | 
| 3 | b,d  | 
| 4 | e  | 
| . | .  | 
+-----+-------+** 

。私は次のような出力をしたい。

**+-----+-------------+ 
| V1 | V2 | V3 | V4 | 
+-----+---------------+ 
| 1 | a | b | c | 
| 2 | a | c | NA | 
| 3 | b | d | NA | 
| 4 | e | NA | NA | 
| . | . | . | . | 
+-----+-------------+** 

これはthis questionのが、アンバランスなサイズで一般化したものです。たとえば、次の例:

myVec <- c("F.US.CLE.V13", "F.US.CA6.U13", "F.US.CA6.U13","F.US.CA6", "F.US", "F") 

答えて

5

それとも、あなたが使用することができますsplitstackshape

cSplit(dat, 2, drop = TRUE,sep=',') 


    V1 V2_1 V2_2 V2_3 
1: 1 a b c 
2: 2 a c NA 
3: 3 b d NA 
4: 4 e NA NA 
+0

これは最も簡単だと思います。迅速な対応に感謝します。 – Rotail

+0

@Rotailうれしい – Wen

3

あなたはdata.table::tstrsplitを使用することができます。

library(data.table) 
setDT(df)[, c(list(V1), tstrsplit(V2, ","))] 

# V1 V2 V3 V4 
#1: 1 a b c 
#2: 2 a c NA 
#3: 3 b d NA 
#4: 4 e NA NA 

myVec 
#[1] "F.US.CLE.V13" "F.US.CA6.U13" "F.US.CA6.U13" "F.US.CA6"  "F.US"   
#[6] "F"   

as.data.table(tstrsplit(myVec, '\\.')) 

# V1 V2 V3 V4 
#1: F US CLE V13 
#2: F US CA6 U13 
#3: F US CA6 U13 
#4: F US CA6 NA 
#5: F US NA NA 
#6: F NA NA NA 
4

このパッケージを試すことができます

library(tidyr) 
DF <- data.frame(V1 = 1:4, V2 = c("a,b,c", "a,c", "b,d","e")) 
separate(DF, V2, into = c("V2", "V3", "V4")) 
#> Warning: Too few values at 3 locations: 2, 3, 4 
#> V1 V2 V3 V4 
#> 1 1 a b c 
#> 2 2 a c <NA> 
#> 3 3 b d <NA> 
#> 4 4 e <NA> <NA> 

あなたはあなたがdplyrtidyrを使用することができますfill引数

separate(DF, V2, into = c("V2", "V3", "V4"), fill = "right") 
#> V1 V2 V3 V4 
#> 1 1 a b c 
#> 2 2 a c <NA> 
#> 3 3 b d <NA> 
#> 4 4 e <NA> <NA> 
1

で警告を抑制することができますしたい場合はとそのseparate機能。 dt2が最終出力です。 tidyrseparateが機能しますが、作成する列の数を事前に知る必要があります。この解決法はそれを必要としません。

library(dplyr) 
library(tidyr) 

# Example data frame 
dt <- data_frame(V1 = 1:4, 
      V2 = c("a,b,c", "a,c", "b,d", "e")) 

# Process the data 
dt2 <- dt %>% 
    separate_rows(V2) %>% 
    rename(Value = V2) %>% 
    group_by(V1) %>% 
    mutate(Col = paste0("V", 1:n() + 1)) %>% 
    spread(Col, Value) 
0

あなたは2行のコードを書いてOKであれば、なぜこのアプローチ: 1)は、特殊文字(コンマ) 2)あなたは 3分解要素の最大数を見つけるに応じて文字列を分割)利用可能な要素を持つテーブルを準備し、必要に応じてNAを追加します。 4)データフレームをまとめて返します。

df <- cbind(1:5, c("a", "a,b,v", "a,c", "d,f,f", "ddd")) 
split.strings <- strsplit(df[,2], ",") 
# 
# get the max length 
max.elems <- max(sapply(split.strings, length)) 
# 
# wrap 
new.data <- sapply(1:max.elems, (function(i){ 
    sapply(1:nrow(df), (function(rw){ 
    if (length(split.strings[[rw]]) >= i) { 
     split.strings[[rw]][i] 
    } else { 
     NA 
    } 
    })) 
})) 
# 
# bind to identifier 
final.df <- data.frame(id = df[,1], 
         new.data, 
         stringsAsFactors = F) 
final.df 
関連する問題