2016-05-24 11 views
1

Ich versuche do von dplyr und tidy von broom zu verwenden, um einige Sachen ordentlich in einen Datenrahmen zu organisieren. Alles funktioniert gut. Aber jetzt versuche ich, auf der Grundlage der Gruppierung innerhalb des gleichen Rohres Wert zu mutieren, und ich kann es nicht funktioniert, was ich will:Bind Spalten zurückgegeben von Do/Tidy von dplyr und Besen funktioniert nicht wie erwartet

Beispiel (mit mtcars Datensatz):

library(dplyr) 
library(broom) 
mtcars %>% group_by(cyl) %>% mutate(n = n()) %>% do(tidy(summary(.$mpg))) 

Ich hatte gehofft, die Ausgabe von summary pro Zyl mit der Anzahl der Beobachtungen zu erhalten, die ich in der Mitte berechnete. Allerdings habe ich nur die Ausgabe von summary erhalten wie folgt:

Source: local data frame [3 x 7] 
Groups: cyl [3] 

    cyl minimum q1 median mean q3 maximum 
    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  4 21.4 22.80 26.0 26.66 30.40 33.9 
2  6 17.8 18.65 19.7 19.74 21.00 21.4 
3  8 10.4 14.40 15.2 15.10 16.25 19.2 

Ausgangswert n fehlt.

Ich habe auch versucht bind_cols und inner_join wie folgt und beide Ergebnis in Fehler unten:

mtcars %>% group_by(cyl) %>% mutate(mpgMean = mean(mpg)) %>% inner_join(., do(tidy(summary(.$mpg)))) 
Error in args[[1]] : subscript out of bounds 
mtcars %>% group_by(cyl) %>% mutate(n = n()) %>% bind_cols(do(tidy(summary(.$mpg)))) 
Error in args[[1]] : subscript out of bounds 

Jede Idee, wie ich diese Arbeit machen kann?

Meine erwartete Ausgabe ist:

Joining by: "cyl" 
Source: local data frame [3 x 8] 

    cyl  n minimum q1 median mean q3 maximum 
    <dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  4 11 21.4 22.80 26.0 26.66 30.40 33.9 
2  6  7 17.8 18.65 19.7 19.74 21.00 21.4 
3  8 14 10.4 14.40 15.2 15.10 16.25 19.2 

Natürlich habe ich dieses Ergebnis bekommen kann dies zu tun:

inner_join(count(mtcars, cyl), mtcars %>% group_by(cyl) %>% do(tidy(summary(.$mpg)))) 

Aber für eine einzelne Rohr Lösung suchen (wenn möglich).

+2

oder einfach: 'mtcars%>% group_by (Zyl)%>% mutieren (n = n ())%>% group_by (cyl, n)%>% do (sauber (zusammenfassung (. $ mpg))) ' – HubertL

+0

Definitiv besser ... wünschte immer noch, es gäbe einen Weg, die Ausgabe von' do' und column bind zu nehmen . 'do' sagt, dass es einen Datenrahmen zurückgibt. – Gopala

+0

Mit data.table: 'as.data.table (mtcars) [, c (. (N = .N), as.list (Zusammenfassung (mpg))), by = cyl]' – Frank

Antwort

2

Verwenden bind_cols innen do

mtcars %>% group_by(cyl) %>% 
      mutate(n = n()) %>% 
      do(bind_cols(tidy(summary(.$mpg)), 
         data.frame(unique(.$n)))) 

oder (bevorzugte Option) verwendet n als variable Gruppierung (mit freundlicher Genehmigung von @Frank):

mtcars %>% group_by(cyl) %>% 
      group_by(n = n(), add=T) %>% 
      do(tidy(summary(.$mpg))) 

Beide geben:

Source: local data frame [3 x 8] 
Groups: cyl, n [3] 

    cyl  n minimum q1 median mean q3 maximum 
    (dbl) (int) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) 
1  4 11 21.4 22.80 26.0 26.66 30.40 33.9 
2  6  7 17.8 18.65 19.7 19.74 21.00 21.4 
3  8 14 10.4 14.40 15.2 15.10 16.25 19.2 
+2

Vereinfachen Sie mit 'mtcars%> % group_by (cyl)%>% group_by (n = n(), add = WAHR)%>% do (ordentlich (zusammenfassung (. $ mpg))) ' – Frank

+0

@coffeinjunky Dies ist eine feine Lösung und besser als die 'inner_join' Lösung Ich bin gekommen. Hoffte, einen Weg zu finden, um 'n' nicht neu zu spezifizieren. Aber wenn es nicht vermeidbar ist, stimme ich zu, das ist eine gute Antwort. – Gopala

+0

@Frank dein ist das Beste, was ich bisher gesehen habe, während es andere gibt, die besser sind als das, was ich ursprünglich erfunden hatte. – Gopala

2

Ich fürchte die idiomatische Weg ist

my_summary = function(x) as.data.frame(as.list(c(n = length(x), summary(x)))) 
mtcars %>% group_by(cyl) %>% do(my_summary(.$mpg)) 

    cyl  n Min. X1st.Qu. Median Mean X3rd.Qu. Max. 
    (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) 
1  4 11 21.4 22.80 26.0 26.66 30.40 33.9 
2  6  7 17.8 18.65 19.7 19.74 21.00 21.4 
3  8 14 10.4 14.40 15.2 15.10 16.25 19.2 

(Ich bin nicht vertraut genug mit broommy_summary schreiben Sie es.)

+1

Wahrscheinlich würden die Paketautoren darauf bestehen, dass nur fortgeschrittene Benutzer 'summary' und' n' gleichzeitig benötigen. Das ist das Schnäppchen, das Sie machen, wenn Sie sich für dplyr anmelden - Sie erhalten eine kohärente Grammatik für die Datenmanipulation, aber eine fehlt ganze Teile der Sprache. – Frank