Урок 4 Обновлённая функция summarise()

4.1 Описание

В этом уроке мы рассмотрим новые возможности функции summarise().

Урок основан на статье “dplyr 1.0.0: new summarise() features”.

4.2 Видео

4.3 Код

#devtools::install_github("tidyverse/dplyr")
library(dplyr)

# Основные изменения
## теперь sunnarise может вернуть
### вектор любой длинны
### дата фрейм любой размерности

# #######################################################
# тестовые данные
# #######################################################
df <- tibble(
  grp = rep(1:2, each = 5), 
  x = c(rnorm(5, -0.25, 1), rnorm(5, 0, 1.5)),
  y = c(rnorm(5, 0.25, 1), rnorm(5, 0, 0.5)),
)

df

# получим минимальные и максимальные значения для каждой группы
# и поместим эти значения в строки
df %>% 
  group_by(grp) %>% 
  summarise(rng = range(x))

## функция range возвращает вектор длинны 2
range(df$x)
## но функция summarise разворачивает его, 
## приводя каждое из возвращаемых значений в новую строку

# тоже самое, но для столбцов
df %>% 
  group_by(grp) %>% 
  summarise(tibble(min = min(x), mean = mean(x)))

# #######################################################
# Расчёт квантилей
# #######################################################
df %>% 
  group_by(grp) %>% 
  summarise(x = quantile(x, c(0.25, 0.5, 0.75)), q = c(0.25, 0.5, 0.75))

# можем избежать дублирования кода и написать функцию для вычисления квантиля
quibble <- function(x, q = c(0.25, 0.5, 0.75)) {
  tibble(x = quantile(x, q), q = q)
}
# используем собственную функцию в summarise
df %>% 
  group_by(grp) %>% 
  summarise(quibble(x, c(0.25, 0.5, 0.75)))

# доработаем функцию таким образом 
# что бы названия столбца подтягивались из аргумена
quibble2 <- function(x, q = c(0.25, 0.5, 0.75)) {
  tibble("{{ x }}" := quantile(x, q), "{{ x }}_q" := q)
}

df %>% 
  group_by(grp) %>% 
  summarise(quibble2(x, c(0.25, 0.5, 0.75)))


# мы не присваивали имена новых столбцов внутри summarise
# потому что если функция возвращает объект сложной стурктуры
# мы получим вложенные дата фреймы
out <- df %>% 
  group_by(grp) %>% 
  summarise(quantile = quibble2(y, c(0.25, 0.75)))

str(out)

# обращаемся к вложенному фрейму
out$y

# или к его столбцам
# по смыслу такая конструкция напоминает объяденённые имена стобцов в электронных таблицах
out$quantile$y_q

# summarise + rowwise
# эта комбинация функций теперь может заменить purrr и apply
tibble(path = dir(pattern = "\\.csv$")) %>% 
  rowwise(path) %>% 
  summarise(readr::read_csv(path))

# #######################################################
# Предыдущие подходы
# #######################################################
# вычисляем квантили
df %>% 
  group_by(grp) %>% 
  summarise(y = list(quibble(y, c(0.25, 0.75)))) %>% 
  tidyr::unnest(y)

df %>% 
  group_by(grp) %>% 
  do(quibble(.$y, c(0.25, 0.75)))

4.4 Упражнение

Вам дана таблица параметров генерации случайной выборки с нормальным распределением (генерировать случайную выборку с нормальным распределением позволяет функция rnorm()).

Для генерации таблицы параметров выполните следующий код:

library(dplyr)

params <- tribble(
 ~sim, ~n, ~mean, ~sd,
    1,  4,     1,   5,
    2,  7,     2,   10,
    3,  10,   -1,   25
)

Теперь сгенерируйте согласно этим параметрам таблицу содержащую в столбце sim номер строки таблицы параметров, а в столбце val сами значения случайных распределений. Для воспроизводимости результатов установите счётчик генерации случайных чисел в позиции 400 (set.seed(400)). Тогда итоговый результат будет иметь следующий вид:

# A tibble: 21 x 2
# Groups:   sim [3]
     sim   val
   <dbl> <dbl>
 1     1 -1.75
 2     1 -3.70
 3     1  2.27
 4     1 13.2 
 5     2  9.87
 6     2 -5.14
 7     2 -8.09
 8     2 -3.57
 9     2  6.77
10     2 29.4 
# ... with 11 more rows