2016-05-13 19 views
3

Ich habe einen Datenrahmen, der einige Statistiken für eine Reihe von Variablen und Szenarien enthält. Die Daten wie folgt aussehen:tidyr Extrakt regulären Ausdruck

df <- data.frame(
    Scenario = c('base','stress','extreme'), 
    x_min = c(-3,-2, -2.5), 
    x_mean = c(0,0.25, 1), 
    x_max = c(2, 1, 3), 
    y_min = c(-1.5, -2, -3), 
    y_mean = c(1, 2, 3), 
    y_max = c(5, 3, 3.5), 
    z_min = c(0, 1, 3), 
    z_mean = c(0.25, 2, 5), 
    z_max = c(2, 4, 7) 
) 

    Scenario x_min x_mean x_max y_min y_mean y_max z_min z_mean z_max 
1  base -3.0 0.00  2 -1.5  1 5.0  0 0.25  2 
2 stress -2.0 0.25  1 -2.0  2 3.0  1 2.00  4 
3 extreme -2.5 1.00  3 -3.0  3 3.5  3 5.00  7 

Ich mag tidyr Ilses sammeln und Extraktionsfunktionen (in ähnlicher Weise wie Hadley Antwort auf this question) wie die Daten in ein Format zu erhalten:

new_df 
    Scenario variable min mean max 
1  base  x -3.0 0.00 2.0 
2 stress  x -2.0 0.25 1.0 
3 extreme  x -2.5 1.00 3.0 
4  base  y -1.5 1.00 5.0 
5 stress  y -2.0 2.00 3.0 
6 extreme  y -3.0 3.00 3.5 
7  base  z 0.0 0.25 2.0 
8 stress  z 1.0 2.00 4.0 
9 extreme  z 3.0 5.00 7.0 

Die Befehl, den ich bisher haben wie folgt aussieht:

new_df <- df %>% 
      gather(key, value, -Scenario) %>% 
      extract(key, c("min", "mean", "max"), "regex") 

Es ist die regex ich bin zu kämpfen. Im Anschluss an die Antwort in der referenzierten Frage oben Ich habe versucht:

"_min|_mean|_max" --> idea being to capture the 3 different groups 

Der Fehler ich Aussehen bekommen wie:

Error in names(l) <- into : 
    'names' attribute [3] must be the same length as the vector [0] 

Was ich denke, dieser Fehler sagt, ist die der reguläre Ausdruck nicht " Suche nach "3 Gruppen zu sortieren in die c("min","mean","max") Ich habe es bestanden.

Welcher reguläre Ausdruck würde das funktionieren lassen? Oder gibt es eine andere bessere Methode?

Antwort

3

Alles, was Sie brauchen, ist

df %>% gather(var, val, -Scenario) %>% 
    separate(var, into = c('var', 'stat'), sep = '_') %>% 
    spread(stat, val) 
# Scenario var max mean min 
# 1  base x 2.0 0.00 -3.0 
# 2  base y 5.0 1.00 -1.5 
# 3  base z 2.0 0.25 0.0 
# 4 extreme x 3.0 1.00 -2.5 
# 5 extreme y 3.5 3.00 -3.0 
# 6 extreme z 7.0 5.00 3.0 
# 7 stress x 1.0 0.25 -2.0 
# 8 stress y 3.0 2.00 -2.0 
# 9 stress z 4.0 2.00 1.0 

Seit Ihrer ersten Spaltennamen schön mit Unterstrichen formatiert sind Trennen Sie die Variable und die Statistik, separate alles, was Sie brauchen, ist sie in zwei Spalten aufgeteilt. spread wird von lang nach breit neu angeordnet.

+1

nehmen kann, was ich brauche! Als Anmerkung musste ich das 'sep'-Argument von' separate' einen regulären Ausdruck machen, da meine Spaltentitel tatsächlich mehrere Unterstriche enthielten (z.B. 'stat_1_min, stat_2_min'). Die Regex, die ich benutzte, war '(_) (?!. * _)' – reidjax

2

Dies kann leicht mit melt von data.table geschähe, wie genau mehrere patterns im measure

library(data.table) 
nm1 <- unique(substr(names(df)[-1], 1, 1)) 
melt(setDT(df), measure = patterns("min$", "mean$", "max$"), 
     value.name= c("min", "mean", "max"))[, variable := nm1[variable]][] 
# Scenario variable min mean max 
#1:  base  x -3.0 0.00 2.0 
#2: stress  x -2.0 0.25 1.0 
#3: extreme  x -2.5 1.00 3.0 
#4:  base  y -1.5 1.00 5.0 
#5: stress  y -2.0 2.00 3.0 
#6: extreme  y -3.0 3.00 3.5 
#7:  base  z 0.0 0.25 2.0 
#8: stress  z 1.0 2.00 4.0 
#9: extreme  z 3.0 5.00 7.0