2017-08-04 3 views
1

Je voudrais diviser un certain format de données d'une colonne en plusieurs colonnes. Voici mes données exemple:Séparez les valeurs dans une colonne en plusieurs colonnes nom et valeur de la colonne

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 

qui sera donne alors la sortie suivante

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 

Je suis en mesure de le faire, mais la méthode que j'utilise implique une boucle à travers chacune de la ligne et effectuer la str_split par chacun des séparateurs afin d'obtenir les données pour chaque ligne et l'ajouter à la trame de sortie finale qui est très lente étant donné que j'aurai 500k lignes par 20 colonnes d'entrée.

Je ne pense pas que ma boucle for est un bon moyen de coder R pour ce cas d'utilisation. Toute aide serait appréciée.

Répondre

1

Nous pouvons utiliser cSplit avec 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

Merci, cela fonctionne. Mais vous pouvez expliquer un peu comment fonctionne le na.locf? – kaexch

+0

@kaexch Lorsqu'il y a des valeurs NA, 'na.locf' remplace les valeurs NA par les valeurs non-NA précédentes – akrun