2016-03-28 10 views
3

Ich würde gerne dplyr Split-Apply-kombinieren-Strategie verwenden, um die summary() Befehl anwenden.mit dplyrs do() mit Zusammenfassung()

einen einfachen Datenrahmen Nehmen:

df <- data.frame(class = c('A', 'A', 'B', 'B'), 
       value = c(100, 120, 800, 880)) 

Im Idealfall würden wir so etwas tun:

df %>% 
    group_by(class) %>% 
    do(summary(.$value)) 

Leider funktioniert das nicht. Irgendwelche Ideen?

Antwort

4

Das Problem ist, dass dplyr 's do() nur mit Eingabe des Formulars data.frame arbeitet.

Die broom package ‚s tidy() Funktion können Ausgänge von summary()data.frame zu konvertieren verwendet werden.

df %>% 
    group_by(class) %>% 
    do(tidy(summary(.$value))) 

Dies gibt:

Source: local data frame [2 x 7] 
Groups: class [2] 

    class minimum q1 median mean q3 maximum 
    (fctr) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) 
1  A  100 105 110 110 115  120 
2  B  800 820 840 840 860  880 
2

Das Verhalten von do ändert sich je nachdem, ob Sie ein benanntes oder unbenanntes Argument angeben. Bei unbenannten Argumenten erwartet es einen data.frame für jede Gruppe, die zusammen gebunden werden. Für benannte Argumente wird eine Zeile für jede Gruppe erstellt und die Ausgabe in eine neue Variable mit diesem Namen geschrieben.

Also in diesem Fall, dass wir es für unbenannte Verwendung klagen (summary kein data.frame erzeugen), sondern die genannte Verwendung funktioniert:

df %>% 
    group_by(class) %>% 
    do(summaries = summary(.$value)) -> 
    df2 

Welche gibt:

Source: local data frame [2 x 2] 
Groups: <by row> 

    class     summaries 
    (fctr)      (chr) 
1  A <S3:summaryDefault, table> 
2  B <S3:summaryDefault, table> 

Wir kann auf eine Zusammenfassung wie folgt zugreifen:

df2$summaries[[1]] 

Geben:

Min. 1st Qu. Median Mean 3rd Qu. Max. 
100  105  110  110  115  120 

alle diese als neue Spalten für df bekommen kann nur, indem zuerst die Ausgabe in eine data.frame erfolgen, wie in den anderen Antworten zu sehen.

So ist die Wurzel des Problems hier, dass summary einen table anstelle eines data.frame ausgibt.

+1

Dank dieser groß ist.Eine andere Möglichkeit, die ich gerade gefunden habe, wäre, die Funktion 'tidy()' aus dem Besenpaket zu verwenden. Aber es zu benennen ist eine sehr einfache Möglichkeit, dies zu vermeiden. –

4

Sie können die SE-Version von data_frame verwenden, das heißt, data_frame_ und ausführen:

df %>% 
    group_by(class) %>% 
    do(data_frame_(summary(.$value))) 

Alternativ können Sie as.list() von data.frame() mit dem Argument gewickelt verwenden check.names = FALSE:

df %>% 
    group_by(class) %>% 
    do(data.frame(as.list(summary(.$value)), check.names = FALSE)) 

Beide Versionen produzieren:

# Source: local data frame [2 x 7] 
# Groups: class [2] 
# 
# class Min. 1st Qu. Median Mean 3rd Qu. Max. 
# (fctr) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) 
# 1  A 100  105 110 110  115 120 
# 2  B 800  820 840 840  860 880 
+0

Danke, dieser Ausgang sieht perfekt aus. Ich habe etwas über SE gelesen, habe es aber nie ganz verstanden. Zu welchem ​​Paket gehören diese Funktionen? Aus der Verwendung von "_" sieht es wie eines von @hadley aus. Ich habe auch einen Weg gefunden, 'tidy()' aus dem Besenpaket zu verwenden. Siehe unten. –

+2

'data_frame' und' data_frame_' stammen von 'dplyr'. Diese Antwort verdient übrigens, soweit es mich betrifft, das Häkchen. – Axeman

+0

Danke, das macht Sinn. Und danke, dass du dich freiwillig gemeldet hast, ich habe es geändert. –

Verwandte Themen