Решения заданий

Задания к первому уроку

  1. Выберите все столбцы, которые заканчиваются на Width.
library(dplyr)
#> Warning: package 'dplyr' was built under R version 4.4.3
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

select(iris, ends_with('Width')) %>% 
  tibble()
#> # A tibble: 150 × 2
#>    Sepal.Width Petal.Width
#>          <dbl>       <dbl>
#>  1         3.5         0.2
#>  2         3           0.2
#>  3         3.2         0.2
#>  4         3.1         0.2
#>  5         3.6         0.2
#>  6         3.9         0.4
#>  7         3.4         0.3
#>  8         3.4         0.2
#>  9         2.9         0.2
#> 10         3.1         0.1
#> # ℹ 140 more rows
  1. Переместите с помощью функции relocate() единственный текстовый столбец в левую часть таблицы.
relocate(iris, where(is.factor)) %>% 
  tibble()
#> # A tibble: 150 × 5
#>    Species Sepal.Length Sepal.Width Petal.Length Petal.Width
#>    <fct>          <dbl>       <dbl>        <dbl>       <dbl>
#>  1 setosa           5.1         3.5          1.4         0.2
#>  2 setosa           4.9         3            1.4         0.2
#>  3 setosa           4.7         3.2          1.3         0.2
#>  4 setosa           4.6         3.1          1.5         0.2
#>  5 setosa           5           3.6          1.4         0.2
#>  6 setosa           5.4         3.9          1.7         0.4
#>  7 setosa           4.6         3.4          1.4         0.3
#>  8 setosa           5           3.4          1.5         0.2
#>  9 setosa           4.4         2.9          1.4         0.2
#> 10 setosa           4.9         3.1          1.5         0.1
#> # ℹ 140 more rows
  1. Замените с помощью функции rename_with() в названии столбцов точку на нижнее подчёркивание, и преобразуйте имена в нижний регистр.
renamer <- function(x) gsub('\\.', '\\_', x) %>% tolower()
rename_with(iris, renamer) %>% 
  tibble()
#> # A tibble: 150 × 5
#>    sepal_length sepal_width petal_length petal_width species
#>           <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#>  1          5.1         3.5          1.4         0.2 setosa 
#>  2          4.9         3            1.4         0.2 setosa 
#>  3          4.7         3.2          1.3         0.2 setosa 
#>  4          4.6         3.1          1.5         0.2 setosa 
#>  5          5           3.6          1.4         0.2 setosa 
#>  6          5.4         3.9          1.7         0.4 setosa 
#>  7          4.6         3.4          1.4         0.3 setosa 
#>  8          5           3.4          1.5         0.2 setosa 
#>  9          4.4         2.9          1.4         0.2 setosa 
#> 10          4.9         3.1          1.5         0.1 setosa 
#> # ℹ 140 more rows

Задания ко второму уроку

  1. Используйте функцию across(), и разделите значения полей имена которых заканчиваются на Length на среднее значение по этим же столбцам.
library(dplyr)

mutate(iris, across(ends_with('Length'), ~ . / mean(.))) %>% 
  tibble()
#> # A tibble: 150 × 5
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#>           <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#>  1        0.873         3.5        0.373         0.2 setosa 
#>  2        0.839         3          0.373         0.2 setosa 
#>  3        0.804         3.2        0.346         0.2 setosa 
#>  4        0.787         3.1        0.399         0.2 setosa 
#>  5        0.856         3.6        0.373         0.2 setosa 
#>  6        0.924         3.9        0.452         0.4 setosa 
#>  7        0.787         3.4        0.373         0.3 setosa 
#>  8        0.856         3.4        0.399         0.2 setosa 
#>  9        0.753         2.9        0.373         0.2 setosa 
#> 10        0.839         3.1        0.399         0.1 setosa 
#> # ℹ 140 more rows
  1. Посчитайте среднее значение столбцов, имена которых начинаются на Sepal сгруппировав данные по столбцу Species.
group_by(iris, Species) %>% 
  summarise(across(starts_with('Sepal'), mean))
#> # A tibble: 3 × 3
#>   Species    Sepal.Length Sepal.Width
#>   <fct>             <dbl>       <dbl>
#> 1 setosa             5.01        3.43
#> 2 versicolor         5.94        2.77
#> 3 virginica          6.59        2.97

Заданиe к третьему уроку

  1. Ваша задача не переворачивая таблицу, добавить в неё 4 столбца:
  • winter_avg_sales - средний объём продаж за зимные месяца;
  • spring_avg_sales - средний объём продаж за весенние месяца;
  • summer_avg_sales - средний объём продаж за летние месяца;
  • autumn_avg_sales - средний объём продаж за осенние месяца;

И оставить из исходной таблицы только столбец с обозначением года, и рассчитанные на предыдущем шаге столбцы.

Решение:

library(dplyr)

rowwise(sales) %>% 
  mutate(
    winter_avg_sales = mean(Dec, Jan, Feb),
    spring_avg_sales = mean(c_across(Mar:May)),
    summer_avg_sales = mean(c_across(Jun:Aug)),
    autumn_avg_sales = mean(c_across(Sep:Nov))
  ) %>% 
  select(year, matches('avg'))
#> # A tibble: 6 × 5
#> # Rowwise: 
#>    year winter_avg_sales spring_avg_sales summer_avg_sales
#>   <int>            <dbl>            <dbl>            <dbl>
#> 1  2000              297             215.             243 
#> 2  2001              263             248.             272 
#> 3  2002              187             241.             189 
#> 4  2003              234             309              305.
#> 5  2004              183             220              301.
#> 6  2005              273             273              275.
#> # ℹ 1 more variable: autumn_avg_sales <dbl>

Заданиe к четвёртому уроку

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

Решение:

library(dplyr)
set.seed(400)

params %>%
   rowwise(sim) %>%
   summarise(val = rnorm(n, mean, sd))

Заданиe к пятому уроку

  1. Ваша задача расчитать фактическую запрлату каждого сотрудника по формуле total = rate * time_rate + bonus - penalty.

Решение:

library(dplyr)

rows_update(salary, bonus, by = 'employee_id') %>% 
  rows_update(penalty, by = 'employee_id') %>% 
  rows_insert(new, by = 'employee_id') %>% 
  left_join(time_rate, by = 'employee_id') %>% 
  mutate(total = rate * time_rate + bonus - penalty)
#> # A tibble: 6 × 6
#>   employee_id  rate bonus penalty time_rate total
#>         <int> <dbl> <dbl>   <dbl>     <dbl> <dbl>
#> 1           1  1000     0     150       1     850
#> 2           2  1200     0       0       1    1200
#> 3           3   700   100       0       1     800
#> 4           4  1500     0     320       0.8   880
#> 5           5  2000   500      80       1    2420
#> 6           6   500     0       0       0.5   250

Заданиe к шестому уроку

1. Аргумент .by: В отличие от group_by(), аргумент .by не создает постоянную группировку в метаданных объекта. Результат операции всегда возвращается несгруппированным (автоматический ungroup), а порядок строк сохраняется исходным (в отличие от group_by, который сортирует группы по алфавиту). 2. Сложные джойны: Используется функция join_by(). Она позволяет описывать условия неравенства (>, >=, <, <=) и перекрытия диапазонов, заменяя старый синтаксис строковых векторов в аргументе by. 3. Функция reframe(): Она предназначена для случаев, когда результат вычислений возвращает более одной строки на группу (например, при использовании quantile() или создании вложенных таблиц). summarise() теперь выдает предупреждение, если результат не является единственным значением, чтобы избежать логических ошибок. 4. Производительность arrange(): Функция была полностью переписана на языке C. Благодаря этому сортировка данных стала работать в 10–100 раз быстрее, особенно на больших датафреймах и при работе с символьными векторами.

Заданиe к седьмому уроку

  1. Проблема filter(): Функция спроектирована для «сохранения» (keep) строк. При попытке инвертировать логику для удаления строк, пользователь вынужден строить сложные булевы выражения и вручную обрабатывать NA, что ведет к ошибкам.
  2. Обработка NA: filter_out() трактует NA как FALSE. Поскольку функция ищет строки для удаления, это означает, что строки с пропусками не будут удалены, так как условие удаления для них не подтверждено.
  3. Логика OR: when_any() позволяет перечислять условия через запятую, объединяя их через оператор «ИЛИ» (|). Это избавляет от нагромождения скобок и делает код читаемым.
  4. Типизация: recode_values() создает новый столбец и может менять его тип (например, из чисел в текст). replace_values() выполняет частичное обновление существующего столбца, гарантируя сохранение исходного типа данных.
  5. Защитное программирование: Этот аргумент заставляет функцию выдавать ошибку, если в данных найдено значение, которое не было описано в правилах перекодировки. Это гарантирует, что пользователь не пропустил ни одного случая в данных.