2017-08-04 222 views
1

我想將某列中的某一格式的數據分成多列。下面是我的樣本數據:將列中的值分隔爲多列名稱和列值

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 

然後將給出以下輸出

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 

我已經能夠做到這一點,但我使用的方法包括循環通過每個行和執行str_split由每個分隔符爲了獲得每行的數據並將其追加到最終輸出數據幀,這是非常緩慢的考慮到我將有500k行20輸入列。

我不認爲我的for循環是一種正確的R方法來編寫此用例。任何幫助將不勝感激。

回答

1

我們可以用cSplitstr_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

謝謝,這是工作。但是你可以解釋一下na.locf如何工作? – kaexch

+0

@kaexch當有NA值時,'na.locf'將NA值替換爲先前的非NA值 – akrun

相關問題