Урок 3 Перебор строк функцией rowwise()
3.1 Описание
В этом видео мы разберёмся с функцией rowwise()
, из пакета dplyr
.
Данная функция позволяет вам осуществить перебор строк таблицы не прибегая к циклам и функциям семейства apply
или им подобным.
В основе урока лежит статья “dplyr 1.0.0: working within rows”.
3.3 Код
#devtools::install_github("tidyverse/dplyr")
library(dplyr)
# test data
df <- tibble(
student_id = 1:4,
test1 = 10:13,
test2 = 20:23,
test3 = 30:33,
test4 = 40:43
)
df
# попытка посчитать среднюю оценку по студету
df %>% mutate(avg = mean(c(test1, test2, test3, test4)))
# используем rowwise для преобразования фрейма
rf <- rowwise(df, student_id)
rf
rf %>% mutate(avg = mean(c(test1, test2, test3, test4)))
# тоже самое с использованием c_across
rf %>% mutate(avg = mean(c_across(starts_with("test"))))
# ###########################
# некоторые арифметические операции векторизированы по умолчанию
df %>% mutate(total = test1 + test2 + test3 + test4)
# этот подход можно использовать для вычисления среднего
df %>% mutate(avg = (test1 + test2 + test3 + test4) / 4)
# так же вы можете использовать некоторые специальные функции
# для вычисления некоторых статистик
df %>% mutate(
min = pmin(test1, test2, test3, test4),
max = pmax(test1, test2, test3, test4),
string = paste(test1, test2, test3, test4, sep = "-")
)
# все векторизированные функции будут работать быстрее чем rowwise
# но rowwise позволяет векторизировать любую функцию
# ##################################
# работа со столбцами списками
df <- tibble(
x = list(1, 2:3, 4:6),
y = list(TRUE, 1, "a"),
z = list(sum, mean, sd)
)
# мы можем перебором обработать каждый список
df %>%
rowwise() %>%
summarise(
x_length = length(x),
y_type = typeof(y),
z_call = z(1:5)
)
# ##################################
# симуляция случайных данных
df <- tribble(
~id, ~ n, ~ min, ~ max,
1, 3, 0, 1,
2, 2, 10, 100,
3, 2, 100, 1000,
)
# используем rowwise для симуляции данных
df %>%
rowwise(id) %>%
mutate(data = list(runif(n, min, max)))
df %>%
rowwise(id) %>%
summarise(x = runif(n, min, max))
# ##################################
# функция nest_by позволяет создавать столбцы списки
by_cyl <- mtcars %>% nest_by(cyl)
by_cyl
# такой подход удобно использовать при построении линейной модели
# используем mutate для подгонки моели под каждую группа данных
by_cyl <- by_cyl %>% mutate(model = list(lm(mpg ~ wt, data = data)))
by_cyl
# теперь с помощью summarise
# можно извлекать сводки или коэфициенты построенной модели
by_cyl %>% summarise(broom::glance(model))
by_cyl %>% summarise(broom::tidy(model))
3.4 Упражнения
В этот раз тестовые данные для выполнения упражнения мы будем генерировать самостоятельно, используйте приведённый ниже код.
# тестовый набор данных
set.seed(400)
year <- 2000:2005
sales <- sapply(
month.abb,
FUN = function(x) round(runif(n = 6, min = 100, max = 400), 0)
)
sales <- as.data.frame(sales, row.names = year)
sales$year <- year
sales
#> Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec year
#> 2000 145 174 342 185 117 313 314 102 382 220 226 297 2000
#> 2001 156 251 286 280 179 176 317 323 247 194 233 263 2001
#> 2002 319 182 329 155 240 177 146 244 370 300 197 187 2002
#> 2003 209 187 238 296 393 234 366 314 198 213 206 234 2003
#> 2004 379 126 263 261 136 201 352 351 362 203 304 183 2004
#> 2005 221 275 374 318 127 376 257 193 340 190 225 273 2005
В результате вы получили продаж, каждая строка которой хранит данные за определённый год, а каждый столбец за определённый месяц года.
Ваша задача не переворачивая таблицу, добавить в неё 4 столбца:
- winter_avg_sales - средний объём продаж за зимные месяца;
- spring_avg_sales - средний объём продаж за весенние месяца;
- summer_avg_sales - средний объём продаж за летние месяца;
- autumn_avg_sales - средний объём продаж за осенние месяца;
И оставить из исходной таблицы только столбец с обозначением года, и рассчитанные на предыдущем шаге столбцы.
Результат вычислений будет выглядить вот так:
# A tibble: 6 x 5
# Rowwise:
year winter_avg_sales spring_avg_sales summer_avg_sales autumn_avg_sales
<int> <dbl> <dbl> <dbl> <dbl>
1 2000 322 226 145 227
2 2001 174 192. 179. 295.
3 2002 106 352. 215. 258.
4 2003 105 260. 334. 206.
5 2004 167 192. 239 254.
6 2005 210 191. 271. 235