percentiles percentil para interpretacion hallar estadistica ejemplos deciles datos cuartiles cuantiles conjunto como calcular agrupados r dplyr tidyr

interpretacion - Usar las funciones de ventana dplyr para calcular percentiles



percentiles estadistica interpretacion (6)

Aquí hay un enfoque de dplyr que evita do pero que requiere una llamada separada a quantile para cada valor de cuantil.

mtcars %>% group_by(cyl) %>% summarise(`25%`=quantile(mpg, probs=0.25), `50%`=quantile(mpg, probs=0.5), `75%`=quantile(mpg, probs=0.75), avg=mean(mpg), n=n()) cyl 25% 50% 75% avg n 1 4 22.80 26.0 30.40 26.66364 11 2 6 18.65 19.7 21.00 19.74286 7 3 8 14.40 15.2 16.25 15.10000 14

Sería mejor si summarise podría devolver múltiples valores con una sola llamada a quantile , pero esto parece ser un problema abierto en el desarrollo dplyr .

ACTUALIZACIÓN: Aquí hay una variación de la respuesta de @ JuliaSilge que usa la anidación para obtener los cuantiles, pero sin el uso del map . Sin embargo, requiere una línea de código adicional para agregar una columna que enumere los niveles de cuantil, ya que no estoy seguro de cómo (o si es posible) capturar los nombres de los cuantiles en una columna separada directamente de la llamada a quantile .

p = c(0.25,0.5,0.75) mtcars %>% group_by(cyl) %>% summarise(quantiles = list(sprintf("%1.0f%%", p*100)), mpg = list(quantile(mpg, p))) %>% unnest

cyl quantiles mpg 1 4 25% 22.80 2 4 50% 26.00 3 4 75% 30.40 4 6 25% 18.65 5 6 50% 19.70 6 6 75% 21.00 7 8 25% 14.40 8 8 50% 15.20 9 8 75% 16.25

Tengo una solución de trabajo, pero estoy buscando una solución más limpia y legible que tal vez aproveche algunas de las funciones más recientes de la ventana dplyr.

Usando el conjunto de datos mtcars, si quiero ver los percentiles 25, 50, 75 y la media y el recuento de millas por galón ("mpg") por el número de cilindros ("cyl"), uso el siguiente código:

library(dplyr) library(tidyr) # load data data("mtcars") # Percentiles used in calculation p <- c(.25,.5,.75) # old dplyr solution mtcars %>% group_by(cyl) %>% do(data.frame(p=p, stats=quantile(.$mpg, probs=p), n = length(.$mpg), avg = mean(.$mpg))) %>% spread(p, stats) %>% select(1, 4:6, 3, 2) # note: the select and spread statements are just to get the data into # the format in which I''d like to see it, but are not critical

¿Hay alguna forma de que pueda hacer esto más limpiamente con dplyr usando algunas de las funciones de resumen (n_tiles, percent_rank, etc.)? Por limpio, me refiero sin la declaración "do".

Gracias


Aquí hay una solución bastante legible que usa dplyr y purrr para devolver cuantiles en un formato ordenado:

Código

library(dplyr) library(purrr) mtcars %>% group_by(cyl) %>% do({x <- .$mpg map_dfr(.x = c(.25, .5, .75), .f = ~ data_frame(Quantile = .x, Value = quantile(x, probs = .x))) })

Resultado

# A tibble: 9 x 3 # Groups: cyl [3] cyl Quantile Value <dbl> <dbl> <dbl> 1 4 0.25 22.80 2 4 0.50 26.00 3 4 0.75 30.40 4 6 0.25 18.65 5 6 0.50 19.70 6 6 0.75 21.00 7 8 0.25 14.40 8 8 0.50 15.20 9 8 0.75 16.25


Esta solución usa solo dplyr y tidyr , le permite especificar sus cuantiles en la cadena dplyr y aprovecha tidyr::crossing() para "apilar" múltiples copias del conjunto de datos antes de agrupar y resumir.

diamonds %>% # Initial data tidyr::crossing(pctile = 0:4/4) %>% # Specify quantiles; crossing() is like expand.grid() dplyr::group_by(cut, pctile) %>% # Indicate your grouping var, plus your quantile var dplyr::summarise(quantile_value = quantile(price, unique(pctile))) %>% # unique() is needed dplyr::mutate(pctile = sprintf("%1.0f%%", pctile*100)) # Optional prettification

Resultado:

# A tibble: 25 x 3 # Groups: cut [5] cut pctile quantile_value <ord> <chr> <dbl> 1 Fair 0% 337.00 2 Fair 25% 2050.25 3 Fair 50% 3282.00 4 Fair 75% 5205.50 5 Fair 100% 18574.00 6 Good 0% 327.00 7 Good 25% 1145.00 8 Good 50% 3050.50 9 Good 75% 5028.00 10 Good 100% 18788.00 11 Very Good 0% 336.00 12 Very Good 25% 912.00 13 Very Good 50% 2648.00 14 Very Good 75% 5372.75 15 Very Good 100% 18818.00 16 Premium 0% 326.00 17 Premium 25% 1046.00 18 Premium 50% 3185.00 19 Premium 75% 6296.00 20 Premium 100% 18823.00 21 Ideal 0% 326.00 22 Ideal 25% 878.00 23 Ideal 50% 1810.00 24 Ideal 75% 4678.50 25 Ideal 100% 18806.00

El unique() es necesario para que dplyr::summarise() sepa que solo desea un valor por grupo.


Este es un enfoque dplyr que usa la función tidy() del paquete broom , lamentablemente aún requiere do() , pero es mucho más simple.

library(dplyr) library(broom) mtcars %>% group_by(cyl) %>% do( tidy(t(quantile(.$mpg))) )

lo que da:

cyl X0. X25. X50. X75. X100. (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) 1 4 21.4 22.80 26.0 30.40 33.9 2 6 17.8 18.65 19.7 21.00 21.4 3 8 10.4 14.40 15.2 16.25 19.2

Tenga en cuenta el uso de t() ya que el paquete de broom no tiene un método para los valores numéricos con nombre.

Esto se basa en mi respuesta anterior para el resumen () aquí .


No estoy seguro de cómo evitar do() en dplyr , pero puede hacerlo con c() y as.list() con data.table de una manera bastante sencilla:

require(data.table) as.data.table(mtcars)[, c(as.list(quantile(mpg, probs=p)), avg=mean(mpg), n=.N), by=cyl] # cyl 25% 50% 75% avg n # 1: 6 18.65 19.7 21.00 19.74286 7 # 2: 4 22.80 26.0 30.40 26.66364 11 # 3: 8 14.40 15.2 16.25 15.10000 14

Sustitúyalo by keyby si lo desea ordenado por columna de cyl .


Si te gusta el uso de purrr::map , ¡puedes hacerlo así!

library(dplyr) library(tidyr) library(broom) library(purrr) mtcars %>% nest(-cyl) %>% mutate(Quantiles = map(data, ~ quantile(.$mpg))) %>% unnest(map(Quantiles, tidy)) #> # A tibble: 15 × 3 #> cyl names x #> <dbl> <chr> <dbl> #> 1 6 0% 17.80 #> 2 6 25% 18.65 #> 3 6 50% 19.70 #> 4 6 75% 21.00 #> 5 6 100% 21.40 #> 6 4 0% 21.40 #> 7 4 25% 22.80 #> 8 4 50% 26.00 #> 9 4 75% 30.40 #> 10 4 100% 33.90 #> 11 8 0% 10.40 #> 12 8 25% 14.40 #> 13 8 50% 15.20 #> 14 8 75% 16.25 #> 15 8 100% 19.20

Una cosa buena de este enfoque es que la salida es ordenada, una observación por fila.