install.packages('tidyverse')
library(tidyverse)
Составлены в формате задание - ответ к нему.
Рассчитано на самопроверку: ваша задача написать такой код, чтобы совпал с моим правильным ответом. Плюс есть еще несколько заданий на подумать и вспомнить материал лекции.
Не стесняйтесь гуглить, это необходимо для решения многих задач в программировании, которые могут встретиться в реальной жизни.
Если вдруг найдутся ошибки/опечатки, пишите на почту e.ubogoeva@alumni.nsu.ru
или в телеграм. Вопросы по заданиям также можно писать на почту или в телеграм, телеграм чуть предпочтительнее.
Установка tidyverse
Сначала необходимо установить и загрузить tidyverse
:
Работа с пайпами
Перепишите следующие выражения с помощью пайпа %>%
:
sin(log(sqrt(1:10), 10))
[1] 0.0000000 0.1499473 0.2363043 0.2965040 0.3424140 0.3793333 0.4100866
[8] 0.4363562 0.4592238 0.4794255
c("Корень из", 2, "равен", sqrt(2))
[1] "Корень из" "2" "равен" "1.4142135623731"
2 %>%
c("Корень из", ., "равен", sqrt(.))
[1] "Корень из" "2" "равен" "1.4142135623731"
Работа со столбцами dplyr::select()
Загрузка данных:
<- read_tsv('https://raw.githubusercontent.com/ubogoeva/tidyverse_tutorial/master/data/wc3_heroes.txt',
wc3_units col_names = TRUE,
na = '-',
name_repair = 'minimal') %>%
::clean_names() janitor
Выберите столбец
hp
%>% wc3_units select(hp)
# A tibble: 71 × 1 hp <dbl> 1 220 2 220 3 420 4 535 5 835 6 290 7 325 8 600 9 200 10 360 # … with 61 more rows
Выберите столбцы
unit
,race
,gold
,armor
%>% wc3_units select(unit, race, gold, armor)
# A tibble: 71 × 4 unit race gold armor <chr> <chr> <dbl> <dbl> 1 Peasant Human 75 0 2 Militia Human NA 4 3 Footman Human 135 2 4 Rifleman Human 205 0 5 Knight Human 245 5 6 Priest Human 135 0 7 Sorceress Human 155 0 8 Spell Breaker Human 215 3 9 Flying Machine Human 90 2 10 Mortar Team Human 180 0 # … with 61 more rows
Выберите столбцы с
hp
поsight
, и сcooldown
поrange
%>% wc3_units select(hp:sight, cooldown:range)
# A tibble: 71 × 7 hp armor_type armor sight cooldown dps range <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> 1 220 Medium 0 80 2 2.75 0 2 220 Heavy 4 140 1.2 10.4 0 3 420 Heavy 2 140 1.35 9.26 0 4 535 Medium 0 140 1.5 14 40 5 835 Heavy 5 140 1.4 24.3 0 6 290 Unarmored 0 140 2 4.25 60 7 325 Unarmored 0 140 1.75 6.29 60 8 600 Medium 3 140 1.9 7.37 25 9 200 Heavy 2 180 2.5 3 0 10 360 Heavy 0 140 3.5 16.6 115 # … with 61 more rows
Выведите столбец
gold
в качестве вектора%>% wc3_units pull(gold)
[1] 75 NA 135 205 245 135 155 215 90 180 195 280 200 NA NA NA NA 75 200 [20] 135 135 220 180 280 130 145 195 255 265 160 NA NA NA NA 60 130 195 210 [39] 145 255 NA 425 425 160 135 NA 155 NA 330 330 NA NA NA 75 120 215 185 [58] 240 230 145 155 385 NA NA NA NA NA NA NA 200 NA
Выведите все столбцы кроме первого
unit
(отрицательная индексация с помощью!
)%>% wc3_units select(!unit)
# A tibble: 71 × 20 race gold wood pop hp armor_…¹ armor sight speed time groun…² damage <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> 1 Human 75 0 1 220 Medium 0 80 190 15 Normal 5.5 2 Human NA NA 1 220 Heavy 4 140 270 NA Normal 12.5 3 Human 135 0 2 420 Heavy 2 140 270 20 Normal 12.5 4 Human 205 30 3 535 Medium 0 140 270 26 Pierce 21 5 Human 245 60 4 835 Heavy 5 140 350 45 Normal 34 6 Human 135 10 2 290 Unarmor… 0 140 270 28 Magic 8.5 7 Human 155 20 2 325 Unarmor… 0 140 270 30 Magic 11 8 Human 215 30 3 600 Medium 3 140 300 28 Normal 14 9 Human 90 30 1 200 Heavy 2 180 400 13 Siege 7.5 10 Human 180 70 3 360 Heavy 0 140 270 40 Siege 58 # … with 61 more rows, 8 more variables: cooldown <dbl>, dps <dbl>, # range <dbl>, air_attack <chr>, damage_2 <dbl>, cooldown_2 <dbl>, # dps_2 <dbl>, range_2 <dbl>, and abbreviated variable names ¹armor_type, # ²ground_attack
Работа со строками dplyr::filter()
, dplyr::slice()
- Выберите юнитов, показатель здоровья
hp
которых больше 950
%>%
wc3_units filter(hp > 950)
# A tibble: 12 × 21
unit race gold wood pop hp armor…¹ armor sight speed time groun…²
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
1 Phoenix Human NA NA NA 1250 Light 1 160 320 NA Magic
2 Tauren Orc 280 80 5 1300 Heavy 3 140 270 44 Normal
3 Kodo B… Orc 255 60 4 1000 Unarmo… 1 140 220 30 Pierce
4 DoC Be… N.Elf NA NA 4 960 Heavy 3 140 270 NA Normal
5 Mounta… N.Elf 425 100 7 1600 Medium 4 120 270 45 Normal
6 Mounta… N.Elf 425 100 7 1600 Medium 10 120 270 45 Siege
7 Chimae… N.Elf 330 70 5 1000 Light 2 160 250 65 Magic
8 Chimae… N.Elf 330 70 5 1000 Light 2 160 250 65 Siege
9 Avatar… N.Elf NA NA NA 1200 Heavy 2 120 320 NA Normal
10 Abomin… Unde… 240 70 4 1175 Heavy 2 140 270 40 Normal
11 Frost … Unde… 385 120 7 1350 Light 1 160 270 65 Magic
12 Infern… Unde… NA NA NA 1500 Heavy 6 140 320 NA Chaos
# … with 9 more variables: damage <dbl>, cooldown <dbl>, dps <dbl>,
# range <dbl>, air_attack <chr>, damage_2 <dbl>, cooldown_2 <dbl>,
# dps_2 <dbl>, range_2 <dbl>, and abbreviated variable names ¹armor_type,
# ²ground_attack
Выберите юнитов орков (
Orc
) с легким (Light
) типом брони (armor_type
)%>% wc3_units filter(race == 'Orc' & armor_type == 'Light')
# A tibble: 2 × 21 unit race gold wood pop hp armor…¹ armor sight speed time groun…² <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr> 1 Wind Ri… Orc 265 40 4 570 Light 0 160 320 35 Pierce 2 Troll B… Orc 160 40 2 325 Light 0 140 320 28 Siege # … with 9 more variables: damage <dbl>, cooldown <dbl>, dps <dbl>, # range <dbl>, air_attack <chr>, damage_2 <dbl>, cooldown_2 <dbl>, # dps_2 <dbl>, range_2 <dbl>, and abbreviated variable names ¹armor_type, # ²ground_attack
Выведите первые 6 юнитов
Undead
с максимальным показателем затраченного дерева (wood
).%>% wc3_units filter(race == 'Undead') %>% slice_max(wood, n = 6)
# A tibble: 7 × 21 unit race gold wood pop hp armor…¹ armor sight speed time groun…² <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr> 1 Frost W… Unde… 385 120 7 1350 Light 1 160 270 65 Magic 2 Abomina… Unde… 240 70 4 1175 Heavy 2 140 270 40 Normal 3 Meat Wa… Unde… 230 50 4 380 Heavy 2 140 220 45 Siege 4 Crypt F… Unde… 215 40 3 550 Medium 0 140 270 30 Pierce 5 Obsidia… Unde… 200 35 3 550 Heavy 4 120 270 45 Magic 6 Gargoyle Unde… 185 30 2 410 Unarmo… 3 160 350 35 Pierce 7 Banshee Unde… 155 30 2 285 Unarmo… 0 140 270 28 Magic # … with 9 more variables: damage <dbl>, cooldown <dbl>, dps <dbl>, # range <dbl>, air_attack <chr>, damage_2 <dbl>, cooldown_2 <dbl>, # dps_2 <dbl>, range_2 <dbl>, and abbreviated variable names ¹armor_type, # ²ground_attack
Хм, почему-то вывелось 7 строчек. Почему это произошло, можно узнать, прочитав справку функции
slice_max()
(аргументwith_ties
).Попробуем вывести только 6 строчек в предыдущем задании.
%>% wc3_units filter(race == 'Undead') %>% slice_max(wood, n = 6, with_ties = FALSE)
# A tibble: 6 × 21 unit race gold wood pop hp armor…¹ armor sight speed time groun…² <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr> 1 Frost W… Unde… 385 120 7 1350 Light 1 160 270 65 Magic 2 Abomina… Unde… 240 70 4 1175 Heavy 2 140 270 40 Normal 3 Meat Wa… Unde… 230 50 4 380 Heavy 2 140 220 45 Siege 4 Crypt F… Unde… 215 40 3 550 Medium 0 140 270 30 Pierce 5 Obsidia… Unde… 200 35 3 550 Heavy 4 120 270 45 Magic 6 Gargoyle Unde… 185 30 2 410 Unarmo… 3 160 350 35 Pierce # … with 9 more variables: damage <dbl>, cooldown <dbl>, dps <dbl>, # range <dbl>, air_attack <chr>, damage_2 <dbl>, cooldown_2 <dbl>, # dps_2 <dbl>, range_2 <dbl>, and abbreviated variable names ¹armor_type, # ²ground_attack
Но вообще лучше сохранять дефолтное значение параметра with_ties
Создание колонок dplyr::mutate()
Создайте новую колонку
is_air_attack
, которая будет заполненаTRUE
, если у юнита есть воздушная атака (air_attack
), иFALSE
, если нет. Выведите на печать колонкиunit
,race
,air_attack
иis_air_attack
%>% wc3_units mutate(is_air_attack = !is.na(air_attack)) %>% select(unit, race, air_attack, is_air_attack)
# A tibble: 71 × 4 unit race air_attack is_air_attack <chr> <chr> <chr> <lgl> 1 Peasant Human <NA> FALSE 2 Militia Human <NA> FALSE 3 Footman Human <NA> FALSE 4 Rifleman Human Pierce TRUE 5 Knight Human <NA> FALSE 6 Priest Human Magic TRUE 7 Sorceress Human Magic TRUE 8 Spell Breaker Human <NA> FALSE 9 Flying Machine Human Pierce TRUE 10 Mortar Team Human <NA> FALSE # … with 61 more rows
Создайте колонку
how_fast
, заполненную значениями: если скоростьspeed
больше 270 - fast, равно 270 - middle, меньше 270 - slow. Выведите на печать колонкиunit
,race
,speed
,how_fast
.%>% wc3_units mutate(how_fast = case_when(speed > 270 ~ 'fast', == 270 ~ 'middle', speed TRUE ~ 'slow')) %>% select(unit, race, speed, how_fast)
# A tibble: 71 × 4 unit race speed how_fast <chr> <chr> <dbl> <chr> 1 Peasant Human 190 slow 2 Militia Human 270 middle 3 Footman Human 270 middle 4 Rifleman Human 270 middle 5 Knight Human 350 fast 6 Priest Human 270 middle 7 Sorceress Human 270 middle 8 Spell Breaker Human 300 fast 9 Flying Machine Human 400 fast 10 Mortar Team Human 270 middle # … with 61 more rows
Сортировка dplyr::arrange()
- Отсортируйте колонку
dps
по убыванию, выберите колонкиunit
,race
,damage
,cooldown
,dps
.
%>%
wc3_units arrange(desc(dps)) %>%
select(unit, race, damage, cooldown, dps)
# A tibble: 71 × 5
unit race damage cooldown dps
<chr> <chr> <dbl> <dbl> <dbl>
1 Phoenix Human 68 1.4 48.6
2 Infernal Undead 54.5 1.35 40.4
3 Frost Wyrm Undead 104 3 34.7
4 Water Elemental 3 Human 45 1.5 30
5 Chimaera N.Elf 75 2.5 30
6 DoC Bear Form N.Elf 36.5 1.5 24.3
7 Knight Human 34 1.4 24.3
8 Siege Engine Human 50 2.1 23.8
9 Water Elemental 2 Human 35 1.5 23.3
10 Gryphon Rider Human 50 2.2 22.7
# … with 61 more rows
Отсортируйте колонку
hp
по возрастанию,armor
по убыванию, выберитеunit
,race
,hp
,armor
.%>% wc3_units arrange(hp, desc(armor)) %>% select(unit, race, hp, armor)
# A tibble: 71 × 4 unit race hp armor <chr> <chr> <dbl> <dbl> 1 Serpent Ward Orc 75 0 2 Wisp N.Elf 120 0 3 Shade Undead 125 0 4 DoC Druid Form N.Elf 130 1 5 Carrion Beetle 1 Undead 140 2 6 Skeleton Warrior Undead 180 1 7 Flying Machine Human 200 2 8 Spirit Wolf Orc 200 0 9 Militia Human 220 4 10 Peasant Human 220 0 # … with 61 more rows
Аггрегация group_by()
+ summarise()
- Посчитайте средний урон и здоровье для юнитов, сгруппированных по типам брони (
armor_type
). Можно сделать это несколькими способами.
%>%
wc3_units group_by(armor_type) %>%
summarise(mean_damage = mean(damage, na.rm = TRUE),
mean_hp = mean(hp, na.rm = TRUE))
# A tibble: 6 × 3
armor_type mean_damage mean_hp
<chr> <dbl> <dbl>
1 Fort 50 700
2 Heavy 28.3 534.
3 Invulnerable 16 500
4 Light 42.9 819.
5 Medium 20.3 514.
6 Unarmored 13.6 423.
%>%
wc3_units group_by(armor_type) %>%
summarise(across(c(damage, hp), function(x) mean(x, na.rm = TRUE)))
# A tibble: 6 × 3
armor_type damage hp
<chr> <dbl> <dbl>
1 Fort 50 700
2 Heavy 28.3 534.
3 Invulnerable 16 500
4 Light 42.9 819.
5 Medium 20.3 514.
6 Unarmored 13.6 423.
Подсчитайте средние по всем числовым переменным, группируя по типу брони. Подсказка: здесь пригодится функция
across()
.%>% wc3_units group_by(armor_type) %>% summarise(across(where(is.numeric), function(x) mean(x, na.rm = TRUE)))
# A tibble: 6 × 17 armor_type gold wood pop hp armor sight speed time damage coold…¹ <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 Fort 195 60 3 700 2 140 220 55 50 2.1 2 Heavy 200. 45.4 2.47 534. 1.76 130. 276. 35.6 28.3 1.85 3 Invulnerable NaN NaN NaN 500 NaN 120 270 NaN 16 1.35 4 Light 263. 58.1 4.1 819. 1 155. 311. 44.5 42.9 1.94 5 Medium 181. 30 2.47 514. 1.2 126 269. 24.1 20.3 2.11 6 Unarmored 164. 28.5 2.36 423. 0.429 144. 296. 30.4 13.6 1.80 # … with 6 more variables: dps <dbl>, range <dbl>, damage_2 <dbl>, # cooldown_2 <dbl>, dps_2 <dbl>, range_2 <dbl>, and abbreviated variable name # ¹cooldown
Преобразование таблиц pivot_longer()
, pivot_wider()
Сначала создадим таблицу
<- wc3_units %>%
wc3_dps mutate(if_summon = if_else((pop == 0) | is.na(pop),
'summoned', 'not_summoned')) %>%
group_by(race, if_summon) %>%
summarise(mean_dps = mean(dps, na.rm = TRUE))
`summarise()` has grouped output by 'race'. You can override using the
`.groups` argument.
wc3_dps
# A tibble: 8 × 3
# Groups: race [4]
race if_summon mean_dps
<chr> <chr> <dbl>
1 Human not_summoned 12.0
2 Human summoned 28.8
3 N.Elf not_summoned 14.8
4 N.Elf summoned 14.5
5 Orc not_summoned 11.3
6 Orc summoned 14.4
7 Undead not_summoned 12.8
8 Undead summoned 14.7
Теперь попробуем превратить таблицу в широкую
<- wc3_dps %>%
wc3_dps_wide pivot_wider(id_cols = race, names_from = if_summon,
values_from = mean_dps)
wc3_dps_wide
# A tibble: 4 × 3
# Groups: race [4]
race not_summoned summoned
<chr> <dbl> <dbl>
1 Human 12.0 28.8
2 N.Elf 14.8 14.5
3 Orc 11.3 14.4
4 Undead 12.8 14.7
Полученную таблицу превратить обратно в длинную
%>%
wc3_dps_wide pivot_longer(cols = c(not_summoned, summoned),
names_to = 'if_summon',
values_to = 'mean_dps')
# A tibble: 8 × 3
# Groups: race [4]
race if_summon mean_dps
<chr> <chr> <dbl>
1 Human not_summoned 12.0
2 Human summoned 28.8
3 N.Elf not_summoned 14.8
4 N.Elf summoned 14.5
5 Orc not_summoned 11.3
6 Orc summoned 14.4
7 Undead not_summoned 12.8
8 Undead summoned 14.7