dplyr - how can I simplify repetitive lines in summarise?

Viewed 37

Given the following input data:

example_data <- 
  data.frame(Group = rep(c("A", "B"), each = 5),
             Values = rnorm(10))

I have the below code I would like to simplify:

example_data %>% 
  group_by(`Group`) %>% 
  summarise(p01 = quantile(Values, probs = 0.1),
            p02 = quantile(Values, probs = 0.2),
            p03 = quantile(Values, probs = 0.3),
            p04 = quantile(Values, probs = 0.4),
            p05 = quantile(Values, probs = 0.5),
            p06 = quantile(Values, probs = 0.6),
            p07 = quantile(Values, probs = 0.7),
            p08 = quantile(Values, probs = 0.8),
            p09 = quantile(Values, probs = 0.9)) %>% 
  pivot_longer(cols = p01:p09, names_to = "Percentiles", values_to = "Percentile Values")

Bonus points if the final table can contain the values 0.1, 0.2, 0.3, ... instead of 001, p02, p03,...

1 Answers

We can pass a vector in probs and then convert to a tibble with as_tibble_row from the vector of quantile output

library(tibble)
library(dplyr)
library(tidyr)
example_data %>%
   group_by(Group) %>% 
   summarise(P = list(quantile(Values, 
       probs = seq(0.1, 0.9, by = 0.1)) %>% 
     as_tibble_row), .groups = 'drop') %>% 
   unnest_wider(P, names_sep =  "")

-output

# A tibble: 2 × 10
  Group `P10%` `P20%`  `P30%` `P40%`  `P50%` `P60%` `P70%` `P80%` `P90%`
  <chr>  <dbl>  <dbl>   <dbl>  <dbl>   <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
1 A     -0.929 -0.723 -0.508  -0.284 -0.0610  0.148  0.357  0.728   1.26
2 B     -0.278 -0.242 -0.0462  0.309  0.665   0.808  0.950  1.19    1.52

The default names can be changed in the end (either programmatically or using indexing to replace)

example_data %>%
   group_by(Group) %>% 
   summarise(P = list(quantile(Values, 
       probs = seq(0.1, 0.9, by = 0.1)) %>% 
     as_tibble_row), .groups = 'drop') %>% 
   unnest_wider(P, names_sep =  "") %>%
  rename_with(~ str_replace(str_remove(.x, "%$"), "(\\d+)", 
   function(x) str_pad(as.numeric(x)/10, width = 2, pad = 0)), starts_with("P"))

-output

# A tibble: 2 × 10
  Group    P01    P02     P03    P04     P05   P06   P07   P08   P09
  <chr>  <dbl>  <dbl>   <dbl>  <dbl>   <dbl> <dbl> <dbl> <dbl> <dbl>
1 A     -0.929 -0.723 -0.508  -0.284 -0.0610 0.148 0.357 0.728  1.26
2 B     -0.278 -0.242 -0.0462  0.309  0.665  0.808 0.950 1.19   1.52
Related