2017-08-04 6 views
1

特定の形式のデータを1つの列から複数の列に分割したいと考えています。以下は私のサンプルデータです:列内の値を複数の列に分割する名前と列の値

次の出力に

id data_apple_A data_apple_B data_apple_C data_apple_D data_orange_A data_orange_B 
1  1    2    3       1    2 
2  1    2       3   1    2 

を与え、私はこれを行うことができましたが、私は使用方法は、行のそれぞれをループ関与し、実行します

df = data.frame(id=c(1,2),data=c('apple:A%1^B%2^C%3_orange:A%1^B%2', 
            'apple:A%1^B%2^D%3_orange:A%3^B%2')) 
# id data 
# 1 apple:A%1^B%2^C%3_orange:A%1^B%2 
# 2 apple:A%1^B%2^D%3_orange:C%3^B%2 

各行のデータを取得し、最後の出力データフレームに追加するために、各セパレータでstr_splitを実行します。これは、500k行×20個の入力列を持つことを考えると非常に遅いです。

私のforループは、このユースケースをコーディングするための適切なR方法ではないと思います。どんな助けもありがとう。

答えて

1

私たちは、これが働いている、str_extract

library(splitstackshape) 
library(zoo) 
library(stringr) 
dt <- cSplit(df, 'data', "\\^|_", fixed = FALSE, "long")[, c('grp', 'grp2', 'val') 
    := .(na.locf(str_extract(data, "^[A-Za-z]+(?=:)")), 
    str_extract(data, "[A-Z](?=[%])"), as.numeric(str_extract(data, "\\d+"))) ][] 
dcast(dt, id ~ paste0("data_", grp) + grp2, value.var = 'val', sep = "_", fill = 0) 
# id data_apple_A data_apple_B data_apple_C data_apple_D data_orange_A data_orange_B 
#1: 1   1   2   3   0    1    2 
#2: 2   1   2   0   3    3    2 
+0

おかげでcSplitを使用することができます。しかし、あなたはna.locfがどのように動作するかを説明することができますか? – kaexch

+0

@kaexch NA値がある場合、 'na.locf'はそのNA値を以前の非NA値で置き換えます – akrun

関連する問題