2015-06-02 21 views
6

Ostatecznie próbuję osiągnąć coś podobnego do następującego, ale wykorzystując dplyr zamiast plyr:Co to jest odpowiednik dplyr plyr :: ldply (tapply) w R?

library(dplyr) 
probs = seq(0, 1, 0.1) 

plyr::ldply(tapply(mtcars$mpg, 
        mtcars$cyl, 
        function(x) { quantile(x, probs = probs) })) 

# .id 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 
# 1 4 21.4 21.50 22.80 22.80 24.40 26.0 27.30 30.40 30.40 32.40 33.9 
# 2 6 17.8 17.98 18.32 18.98 19.40 19.7 20.48 21.00 21.00 21.16 21.4 
# 3 8 10.4 11.27 13.90 14.66 15.04 15.2 15.44 15.86 16.76 18.28 19.2 

Najlepszym dplyr równoważne mogę wymyślić coś takiego:

library(tidyr) 
probs = seq(0, 1, 0.1) 

mtcars %>% 
    group_by(cyl) %>% 
    do(data.frame(prob = probs, stat = quantile(.$mpg, probs = probs))) %>% 
    spread(prob, stat) 

# cyl 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 
# 1 4 21.4 21.50 22.80 22.80 24.40 26.0 27.30 30.40 30.40 32.40 33.9 
# 2 6 17.8 17.98 18.32 18.98 19.40 19.7 20.48 21.00 21.00 21.16 21.4 
# 3 8 10.4 11.27 13.90 14.66 15.04 15.2 15.44 15.86 16.76 18.28 19.2 

Zauważ, że II również trzeba użyć tidyr::spread. Ponadto zauważ, że utraciłem formatowanie kolumn nagłówków kolumn z korzyścią zastąpienia .id wartością cyl w pierwszej kolumnie.

Pytania:

  1. Czy istnieje lepszy dplyr oparty Podejście do realizacji tego tapply %>% ldply łańcuch?
  2. Czy istnieje sposób, aby uzyskać najlepsze z obu światów , nie przeskakując przez zbyt wiele obręczy? Oznacza to, że należy uzyskać formatowanie kolumny % i właściwą kolumnę cyl dla pierwszej kolumny?

Odpowiedz

7

Korzystanie dplyr

library(dplyr) 
mtcars %>% 
    group_by(cyl) %>% 
    do(data.frame(as.list(quantile(.$mpg,probs=probs)), check.names=FALSE)) 
# cyl 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 
#1 4 21.4 21.50 22.80 22.80 24.40 26.0 27.30 30.40 30.40 32.40 33.9 
#2 6 17.8 17.98 18.32 18.98 19.40 19.7 20.48 21.00 21.00 21.16 21.4 
#3 8 10.4 11.27 13.90 14.66 15.04 15.2 15.44 15.86 16.76 18.28 19.2 

albo opcję korzystania data.table

library(data.table) 
as.data.table(mtcars)[, as.list(quantile(mpg, probs=probs)) , cyl] 
# cyl 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 
#1: 6 17.8 17.98 18.32 18.98 19.40 19.7 20.48 21.00 21.00 21.16 21.4 
#2: 4 21.4 21.50 22.80 22.80 24.40 26.0 27.30 30.40 30.40 32.40 33.9 
#3: 8 10.4 11.27 13.90 14.66 15.04 15.2 15.44 15.86 16.76 18.28 19.2 
+0

czy wyjaśnić "check.names = FALSE"? – JasonAizkalns

+0

@JasonAlzkains Jest to argument w 'data.frame', gdzie domyślną opcją jest' check.names = TRUE'. Tak więc, jeśli nazwy kolumn zaczynają się od wartości nieliczbowych, zostanie do nich dodane wyrażenie "X". Odpowiedni kod to 'if (check.names) vnames <- make.names (vnames, unique = TRUE)' – akrun

5

@ wersji akrun jest dobra, ale chciałbym używać data_frame_ wewnątrz rachunku do.

mtcars %>% 
    group_by(cyl) %>% 
    do(data_frame_(quantile(.$mpg, probs = probs))) 
## Source: local data frame [3 x 12] 
## Groups: cyl 
## 
## cyl 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 
## 1 4 21.4 21.50 22.80 22.80 24.40 26.0 27.30 30.40 30.40 32.40 33.9 
## 2 6 17.8 17.98 18.32 18.98 19.40 19.7 20.48 21.00 21.00 21.16 21.4 
## 3 8 10.4 11.27 13.90 14.66 15.04 15.2 15.44 15.86 16.76 18.28 19.2 

Po dalszych badaniach na dlaczego to działa, wygląda data_frame_ różni się od zwykłej logiki SE stosowanych w dplyr. data_frame_ przyjmuje tylko jeden argument columns i naprawdę oczekuje argumentu lazy_dots.

Jeśli zamiast tego dostaje wektor, działa, ponieważ działa leniwy wynik poszczególnych argumentów. Tak więc ta funkcja używania data_frame_ na takim wektorze może w rzeczywistości być błędem.

+0

Nie wiedziałem, że 'data_frame_' działa w zwarty sposób. Dobra informacja! – akrun

+0

Czy istnieje sposób generowania danych wyjściowych w długiej formie za pomocą 'data_frame _()', a następnie? – Arun

+0

@Arun: Możesz użyć 'lazy_dots', ale to wydaje się nieco zbyt skomplikowane:' data_frame_ (lazyeval :: lazy_dots (quantile (. $ Mpg, probs = probs))) '). Nie znam prostszego rozwiązania. Oczywiście jest to odpowiednik 'data_frame (kwantyle (. $ Mpg, probs = probs))'. – shadow

Powiązane problemy