2017-10-27 1 views
0

Ich versuche die Reihenfolge der Spalten zu erhalten, wenn ich sie vom Wide- zum Long-Format zusammenarbeite. Das Problem, das ich habe, ist, nachdem ich gather und summarize die Bestellung verloren habe. Die Anzahl der Spalten ist riesig, daher möchte ich die Bestellung nicht manuell eingeben.Reihenfolge der Spalten beibehalten, wenn vom Wide- zum Long-Format gewechselt wird

Hier ist ein Beispiel:

library(tidyr) 
library(dplyr) 

N <- 4 
df <- data.frame(sample = c(1,1,2,2), 
       y1.1 = rnorm(N), y2.1 = rnorm(N), y10.1 = rnorm(N)) 
> df 
    sample  y1.1  y2.1  y10.1 
1  1 1.040938 0.8851727 -0.3617224 
2  1 1.175879 1.0009824 -1.1352406 
3  2 -1.501832 0.3446469 -1.8687008 
4  2 -1.326817 0.4434628 -0.8795962 

Was ich will, ist die Reihenfolge der Spalten zu bewahren. Nachdem ich etwas manipuliert habe, ist die Reihenfolge verloren. Gesehen hier:

dfg <- df %>% 
    gather(key="key", value="value", -sample) %>% 
    group_by(sample, key) %>% 
    summarize(mean = mean(value)) 

> filter(dfg, sample == 1) 
    sample key  mean 
    <dbl> <chr>  <dbl> 
1  1 y1.1 0.2936335 
2  1 y10.1 0.6170505 
3  1 y2.1 -0.2250543 

Sie können sehen, wie es y10.1 vor y2.1 bringt, die ich nicht will. Was ich will, ist, dass die Ordnung aufrecht zu erhalten, hier zu sehen:

dfg <- df %>% 
    gather(key="key", value="value", -sample) 

> filter(dfg, sample == 1) 
    sample key  value 
1  1 y1.1 0.60171521 
2  1 y1.1 -0.01444823 
3  1 y2.1 0.81566726 
4  1 y2.1 -1.26577581 
5  1 y10.1 0.41686388 
6  1 y10.1 0.81723707 

Aus irgendeinem Grund die group_by und summarize Operationen die Reihenfolge zu ändern. Ich bin mir nicht sicher warum. Ich habe versucht, den ungroup Befehl, aber das tut nichts. Wie ich bereits sagte, hat mein tatsächlicher Datenrahmen viele Spalten und ich muss die Reihenfolge beibehalten. Der Grund, die Ordnung zu bewahren, ist, dass ich die Daten in der richtigen Reihenfolge darstellen kann.

Irgendwelche Ideen?

Antwort

1

Oder Sie können die Schlüsselspalte auf einen Faktor mit Ebenen widerspiegelt die ursprüngliche Spaltennamen bestellen konvertieren:

df %>% 
    gather(key="key", value="value", -sample) %>% 
    mutate(key=factor(key, levels=names(df)[-1])) %>% # add this line to convert the key to a factor 
    group_by(sample, key) %>% 
    summarize(mean = mean(value)) %>% 
    filter(sample == 1) 

# A tibble: 3 x 3 
# Groups: sample [1] 
# sample key  mean 
# <dbl> <fctr>  <dbl> 
#1  1 y1.1 0.8310786 
#2  1 y2.1 -1.2596933 
#3  1 y10.1 0.8208812 
+0

ich dies als Antwort ausgewählt, weil es die allgemeine Lösung ist. Die Lösung von @Moody_Mudskipper bietet jedoch eine einzigartige Option, die es numerisch sortiert, was in den gleichen Fällen gewünscht ist (wo die Spalten nicht in der gewünschten Reihenfolge sind). –

1

Ich fand eine praktikable Lösung mit einer Nachschlagetabelle. Es scheint für mich zu funktionieren, weil ich die Spaltennamen extrahieren und dem Spaltennamen eine geordnete Nummer zuweisen und dann mit meiner data.frame paaren kann.

Hier ist die Lösung:

lookup <- tibble(key = c("y1.1", "y2.1", "y10.1"), 
       index = c(1,2,3)) 

> left_join(dfg, lookup, by="key") 
# A tibble: 6 x 4 
    sample key  mean index 
    <dbl> <chr>  <dbl> <dbl> 
1  1 y1.1 0.2936335  1 
2  1 y10.1 0.6170505  3 
3  1 y2.1 -0.2250543  2 
4  2 y1.1 1.3652070  1 
5  2 y10.1 0.9889233  3 
6  2 y2.1 0.5216553  2 
0

Noch eine andere Art und Weise zu arrange könnte die Datenrahmen, der eine angepasste Version der Schlüsselspalte verwendet, nach der sortiert werden soll:

library(dplyr) 
library(tidyr) 

df %>% 
    gather(key="key", value="value", -sample) %>% 
    group_by(sample, key) %>% 
    summarize(mean = mean(value)) %>% 
    arrange(as.numeric(stringr::str_replace(key, "y", "")), .by_group = TRUE) 

#> # A tibble: 6 x 3 
#> # Groups: sample [2] 
#> sample key  mean 
#> <dbl> <chr>  <dbl> 
#> 1  1 y1.1 0.07001689 
#> 2  1 y2.1 1.15349430 
#> 3  1 y10.1 1.18266024 
#> 4  2 y1.1 0.42616604 
#> 5  2 y2.1 1.05891682 
#> 6  2 y10.1 -0.12561209 
+0

Wird im Wesentlichen der Schlüssel in numerisch konvertiert und danach sortiert? –

+0

Hallo @LloydChristmas, ja du hast Recht. Es macht dasselbe wie die jüngere Antwort von Moody_Mudskipper mit der besser lesbaren Funktion 'parse_number'. Sie müssen '.by_group = TRUE' hinzufügen, wenn Sie möchten, dass das Endergebnis nach den gruppierten Variablen sortiert wird, gefolgt von dem Schlüssel. – markdly

1

Wenn Ihre Spalten wirklich durch die Anzahl geordnet enthält, sollte diese Arbeit:

library(readr) 

df %>% 
    gather(key="key", value="value", -sample) %>% 
    group_by(sample, key)   %>% 
    summarize(mean = mean(value)) %>% 
    arrange(parse_number(key)) %>% # <- sorting by number contained in key 
    filter(sample == 1) 

# # A tibble: 3 x 3 
# # Groups: sample [1] 
#  sample key  mean 
# <dbl> <chr>  <dbl> 
# 1  1 y1.1 -0.9236688 
# 2  1 y2.1 -0.2168337 
# 3  1 y10.1 0.5041981 
Verwandte Themen