6 Решения_заданий
6.1 Вектор
- Посчитайте логарифм от 8912162342 по основанию 6
log(8912162342, 6)
## [1] 12.7867
- Теперь натуральный логарифм 10 и умножьте его на 5
log(10)*5
## [1] 11.51293
- Создайте вектор от 1 до 20
1:20
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
- Создайте вектор от 20 до 1
20:1
## [1] 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
- Создайте вектор от 1 до 20 и снова до 1. Число 20 должно присутствовать только один раз!
c(1:20, 19:1)
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 19 18 17
## [24] 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
- Создайте вектор 2, 4, 6, … , 18, 20
seq(2,20, 2)
## [1] 2 4 6 8 10 12 14 16 18 20
- Создайте вектор из одной единицы, двух двоек, трех троек, …. , девяти девяток
rep(1:9, 1:9)
## [1] 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7 8 8 8 8 8 8 8
## [36] 8 9 9 9 9 9 9 9 9 9
- Сделайте вектор vec, в котором соедините
3
, а также значения"Мой"
и"вектор"
.
vec <- c(3, "Мой", "вектор")
vec
## [1] "3" "Мой" "вектор"
- Вычесть
TRUE
из 10
10 - TRUE
## [1] 9
- Соедините значение
10
иTRUE
в векторvec
vec <- c(10, TRUE)
vec
## [1] 10 1
- Соедините вектор
vec
и значение"r"
:
c(vec, "r")
## [1] "10" "1" "r"
- Соедините значения
10
,TRUE
,"r"
в вектор.
c(10, TRUE, "r")
## [1] "10" "TRUE" "r"
6.2 Вектор. Операции с векторами
Создайте вектор p
, состоящий из значений 4, 5, 6, 7, и вектор q
, состоящий из 0, 1, 2, 3.
p <- 4:7
p
## [1] 4 5 6 7
q <- 0:3
q
## [1] 0 1 2 3
Посчитайте поэлементную сумму векторов p
и q
:
p + q
## [1] 4 6 8 10
Посчитайте поэлементную разницу p
и q
:
p - q
## [1] 4 4 4 4
Поделите каждый элемент вектора p
на соответствующий ему элемент вектора q
:
О, да, Вам нужно делить на 0!
p/q
## [1] Inf 5.000000 3.000000 2.333333
Возведите каждый элемент вектора p
в степень соответствующего ему элемента вектора q
:
p^q
## [1] 1 5 36 343
Создайте вектор квадратов чисел от 1 до 10:
(1:10)^2
## [1] 1 4 9 16 25 36 49 64 81 100
Создайте вектор 0, 2, 0, 4, … , 18, 0, 20
1:20 * 0:1
## [1] 0 2 0 4 0 6 0 8 0 10 0 12 0 14 0 16 0 18 0 20
6.3 Вектор. Индексирование
Создайте вектор vec1
:
vec1 <- c(3, 5, 2, 1, 8, 4, 9, 10, 3, 15, 1, 11)
- Найдите второй элемент вектора
vec1
:
vec1[2]
## [1] 5
- Найдите последний элемент вектора
vec1
vec1[length(vec1)]
## [1] 11
- Найдите все значения вектора
vec1
, которые больше 4
vec1[vec1>4]
## [1] 5 8 9 10 15 11
- Найдите все значения вектора vec1, которые больше 4, но меньше 10
vec1[vec1>4 & vec1<10]
## [1] 5 8 9
- Возведите в квадрат каждое значение вектора
vec1
vec1^2
## [1] 9 25 4 1 64 16 81 100 9 225 1 121
- Возведите в квадрат каждое значение вектора на нечетной позиции и извлеките корень из каждого значения на четной позиции вектора
vec1
vec1 ^ c(2, 0.5)
## [1] 9.000000 2.236068 4.000000 1.000000 64.000000 2.000000 81.000000
## [8] 3.162278 9.000000 3.872983 1.000000 3.316625
- Создайте вектор
vec2
, в котором будут значения все значенияvec1
, которые меньше 10 будут заменены наNA
.
vec2 <- vec1
vec2[vec2<10] <- NA
vec2
## [1] NA NA NA NA NA NA NA 10 NA 15 NA 11
- Посчитайте сумму
vec2
с помощью функцииsum()
. ОтветNA
не считается!
sum(vec2, na.rm = TRUE)
## [1] 36
- Создайте вектор 2, 4, 6, … , 18, 20 как минимум 2 новыми способами
Знаю, это задание может показаться бессмысленным, но это очень базовая операция, с помощью которой можно, например, разделить данные на две части. Чем больше способов Вы знаете, тем лучше!
(1:20)[c(F,T)]
## [1] 2 4 6 8 10 12 14 16 18 20
#(1:10)*2
6.4 Матрицы
- Создайте матрицу 4х4, состоящую из единиц. Назовите ее
M
M <- matrix(rep(1, 16), ncol = 4)
M
## [,1] [,2] [,3] [,4]
## [1,] 1 1 1 1
## [2,] 1 1 1 1
## [3,] 1 1 1 1
## [4,] 1 1 1 1
- Поменяйте все некрайние значения матрицы
M
(то есть значения на позициях [2,2], [2,3], [3,2] и [3,3]) на число 2.
M[2:3, 2:3] <- 2
M
## [,1] [,2] [,3] [,4]
## [1,] 1 1 1 1
## [2,] 1 2 2 1
## [3,] 1 2 2 1
## [4,] 1 1 1 1
- Выделите второй и третий столбик из матрицы
M
M[,2:3]
## [,1] [,2]
## [1,] 1 1
## [2,] 2 2
## [3,] 2 2
## [4,] 1 1
- Сравните (
==
) вторую колонку и вторую строчку матрицыM
M[,2] == M[2,]
## [1] TRUE TRUE TRUE TRUE
- Создайте таблицу умножения (9х9) в виде матрицы. Сохраните ее в переменную
tab
:
tab <- matrix(rep(1:9, rep(9,9))*(1:9), nrow = 9)
tab
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
## [1,] 1 2 3 4 5 6 7 8 9
## [2,] 2 4 6 8 10 12 14 16 18
## [3,] 3 6 9 12 15 18 21 24 27
## [4,] 4 8 12 16 20 24 28 32 36
## [5,] 5 10 15 20 25 30 35 40 45
## [6,] 6 12 18 24 30 36 42 48 54
## [7,] 7 14 21 28 35 42 49 56 63
## [8,] 8 16 24 32 40 48 56 64 72
## [9,] 9 18 27 36 45 54 63 72 81
#Еще
#outer(1:9, 1:9, "*")
#1:9 %o% 1:9
- Из матрицы
tab
выделите подматрицу, включающую в себя только строчки с 6 по 8 и столбцы с 3 по 7.
tab[6:8, 3:7]
## [,1] [,2] [,3] [,4] [,5]
## [1,] 18 24 30 36 42
## [2,] 21 28 35 42 49
## [3,] 24 32 40 48 56
- Создайте матрицу с логическими значениями, где
TRUE
, если в этом месте в таблице умножения (tab
) двузначное число иFALSE
, если однозначное.
Матрица - это почти вектор. К нему можно обращаться с единственным индексом.
tab>=10
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
## [1,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [2,] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
## [3,] FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE
## [4,] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [5,] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [6,] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [7,] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [8,] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [9,] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
- Создайте матрицу
tab2
, в которой все значенияtab
меньше 10 заменены на 0.
tab2 <- tab
tab2[tab<10] <- 0
tab2
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
## [1,] 0 0 0 0 0 0 0 0 0
## [2,] 0 0 0 0 10 12 14 16 18
## [3,] 0 0 0 12 15 18 21 24 27
## [4,] 0 0 12 16 20 24 28 32 36
## [5,] 0 10 15 20 25 30 35 40 45
## [6,] 0 12 18 24 30 36 42 48 54
## [7,] 0 14 21 28 35 42 49 56 63
## [8,] 0 16 24 32 40 48 56 64 72
## [9,] 0 18 27 36 45 54 63 72 81
6.5 Списки
Дан список list_1
:
list_1 = list(numbers = 1:5, letters = letters, logic = T)
list_1
## $numbers
## [1] 1 2 3 4 5
##
## $letters
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q"
## [18] "r" "s" "t" "u" "v" "w" "x" "y" "z"
##
## $logic
## [1] TRUE
- Найдите первый элемент списка. Ответ должен быть списком.
list_1[1]
## $numbers
## [1] 1 2 3 4 5
- Теперь найдите содержание первого элемента списка двумя разными способами. Ответ должен быть вектором.
list_1[[1]]
## [1] 1 2 3 4 5
list_1$numbers
## [1] 1 2 3 4 5
Теперь возьмите первый элемент содержания первого элемента списка. Ответ должен быть вектором.
list_1[[1]][1]
## [1] 1
Создайте список list_2
, содержащий в себе два списка list_1
с именами pupa
и lupa
.
list_2 = list(pupa = list_1, lupa = list_1)
list_2
## $pupa
## $pupa$numbers
## [1] 1 2 3 4 5
##
## $pupa$letters
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q"
## [18] "r" "s" "t" "u" "v" "w" "x" "y" "z"
##
## $pupa$logic
## [1] TRUE
##
##
## $lupa
## $lupa$numbers
## [1] 1 2 3 4 5
##
## $lupa$letters
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q"
## [18] "r" "s" "t" "u" "v" "w" "x" "y" "z"
##
## $lupa$logic
## [1] TRUE
Извлеките первый элемент списка, из него - второй полэлемент, а из него - третье значение
list_2[[1]][[2]][3]
## [1] "c"
6.6 Датафрейм
- Кто является 274ым персонажем в
got
датафрейме? Из какого он дома?
got[274, 1:2]
## Name Allegiances
## 274 Gendry None
- Найдите имена всех персонажей из дома (
Allegiances
)"Tyrell"
и"House Tyrell"
.
got[got$Allegiances %in% c("Tyrell", "House Tyrell"), "Name"]
## [1] "Alerie Hightower" "Alla Tyrell" "Alyn Ambrose"
## [4] "Arryk (Guard)" "Arwyn Oakheart" "Bayard Norcross"
## [7] "Blue Bard" "Butterbumps" "Elinor Tyrell"
## [10] "Erryk (Guard)" "Garlan Tyrell" "Hobber Redwyne"
## [13] "Horas Redwyne" "Janna Tyrell" "Kerwin"
## [16] "Leo Tyrell" "Leonette Fossoway" "Loras Tyrell"
## [19] "Mace Tyrell" "Margaery Tyrell" "Megga Tyrell"
## [22] "Meredyth Crane" "Olenna Redwyne" "Paxter Redwyne"
## [25] "Randyll Tarly" "Talbert Serry"
- Создайте новый датафрейм
greyjoy_women
, который будет включать в себя только женщин Грейджоев ("Greyjoy"
,"House Greyjoy"
)
greyjoy_women <- got[got$Allegiances %in% c("Greyjoy", "House Greyjoy") & got$Gender == 0, ]
greyjoy_women
## Name Allegiances Death.Year Book.of.Death
## 58 Asha Greyjoy House Greyjoy NA NA
## 248 Falia Flowers Greyjoy NA NA
## 313 Gwin Goodbrother Greyjoy NA NA
## 319 Gysella Goodbrother Greyjoy NA NA
## 806 Three-Tooth Greyjoy NA NA
## Death.Chapter Book.Intro.Chapter Gender Nobility GoT CoK SoS FfC DwD
## 58 NA 11 0 1 0 1 0 1 1
## 248 NA 29 0 0 0 0 0 1 0
## 313 NA 1 0 1 0 0 0 1 0
## 319 NA 1 0 1 0 0 0 1 0
## 806 NA 11 0 0 0 0 0 1 0
## Is.Alive Houses info
## 58 Alive Greyjoy Asha Greyjoy from House Greyjoy is Alive
## 248 Alive Greyjoy Falia Flowers from House Greyjoy is Alive
## 313 Alive Greyjoy Gwin Goodbrother from House Greyjoy is Alive
## 319 Alive Greyjoy Gysella Goodbrother from House Greyjoy is Alive
## 806 Alive Greyjoy Three-Tooth from House Greyjoy is Alive
- Сколько всего женских персонажей в книгах “Песни льда и пламени”?
sum(got$Gender == 0)
## [1] 157
- Сколько всего женских персонажей дворянского происхождения в книгах “Песни льда и пламени”?
sum((got$Gender == 0) & (got$Nobility == 1))
## [1] 84
- Поcчитатйе процентную (!) долю знати от общего числа персонажей (
Nobility
) вNight's Watch
.
mean(got[got$Allegiances == "Night's Watch", "Nobility"])*100
## [1] 9.482759
- Поcчитатйе процентную (!) долю знати от общего числа персонажей (
Nobility
) уLannister
.
mean(got[got$Allegiances == "Lannister", "Nobility"])*100
## [1] 71.60494
- Какая из книг цикла самая кровавая? Для ответа на этот вопрос подсчитайте таблицу частот для колонки
got$Book.of.Death
:
Это можно сделать с помощью функции
table()
, но в дальнейшем Вы узнаете и другие способы - подобная задача возникает достаточно часто.
table(got$Book.of.Death)
##
## 1 2 3 4 5
## 49 73 97 27 61
6.7 Создание функций
- Создайте функцию
plus_one()
, которая принимает число и возвращает это же число + 1
plus_one <- function(x) x+1
plus_one(41)
## [1] 42
- Создайте функцию
kvadrat()
возвращающее число в квадрате
kvadrat <- function(x) x*x
kvadrat(6)
## [1] 36
- Создайте функцию
century()
, которая превращает год в век. Возможно, понадобится вспомнить, как года переводятся в века.
Здесь нужно немного погуглить.
century <- function(x) floor((x-1)/100)+1
century(1999:2002)
## [1] 20 20 21 21
- *А теперь сделайте функцию
century_roman()
, которая переводит год в век, записанный римскими цифрами!
Здесь нужно просто немного погуглить - возможно, для создания римских цифр есть уже готовая функция? Прежде созданные функции можно использовать для создания новых функций!
century_roman <- function(x) as.roman(century(x))
century_roman(1999:2002)
## [1] XX XX XXI XXI
- *Напишите функцию
is_prime()
, которая проверяет, является ли число простым.
Здесь может понадобиться оператор для получения остатка от деления:
%%
. Еще может пригодиться функцияany()
- она возвращаетTRUE
, если в векторе есть хотя бы одинTRUE
is_prime <- function(x) !any(x%%(2:(x-1)) == 0)
is_prime(2017)
## [1] TRUE
is_prime(2019)
## [1] FALSE
2019/3 #2019 делится на 3 без остатка
## [1] 673
is_prime(2020)
## [1] FALSE
- *Создайте функцию
monotonic()
, которая принимает возвращаетTRUE
, если значения в векторе не убывают (то есть каждое следующее - больше или равно предыдущему) или не возврастают.
monotonic <- function(x) all(diff(x)>=0) | all(diff(x)<=0)
monotonic(1:7)
## [1] TRUE
monotonic(c(1:5,5:1))
## [1] FALSE
monotonic(6:-1)
## [1] TRUE
monotonic(c(1:5, rep(5, 10), 5:10))
## [1] TRUE
6.8 Семейство apply()
- Посчитайте, в какой из 5 книг больше всего персонажей.
apply(got[, 9:13], 2, sum)
## GoT CoK SoS FfC DwD
## 250 324 389 250 261
#Без apply():
#colSums(got[, 9:13])
#Еще:
#sapply(got[,9:13], sum)
- Сделайте датафрейм
heroes
с персонажами, которые присутствовали во всех книгах.
heroes <- got[apply(got[, 9:13], 1, sum) == 5, ]
heroes
## Name Allegiances Death.Year Book.of.Death
## 56 Arya Stark Stark NA NA
## 63 Balon Swann Lannister NA NA
## 104 Boros Blount Baratheon NA NA
## 131 Cersei Lannister House Lannister NA NA
## 302 Grenn Night's Watch NA NA
## 345 Harys Swyft Lannister NA NA
## 383 Jaime Lannister Lannister NA NA
## 410 Jon Snow Night's Watch NA NA
## 436 Kevan Lannister House Lannister 300 5
## 452 Lancel Lannister Lannister NA NA
## 548 Meryn Trant Lannister NA NA
## 652 Pycelle House Lannister 300 5
## 741 Samwell Tarly Night's Watch NA NA
## Death.Chapter Book.Intro.Chapter Gender Nobility GoT CoK SoS FfC DwD
## 56 NA 2 0 1 1 1 1 1 1
## 63 NA 29 1 1 1 1 1 1 1
## 104 NA 8 1 1 1 1 1 1 1
## 131 NA 4 0 1 1 1 1 1 1
## 302 NA 19 1 0 1 1 1 1 1
## 345 NA 69 1 1 1 1 1 1 1
## 383 NA 5 1 1 1 1 1 1 1
## 410 NA 1 1 1 1 1 1 1 1
## 436 NA 56 1 1 1 1 1 1 1
## 452 NA 47 1 1 1 1 1 1 1
## 548 NA 8 1 1 1 1 1 1 1
## 652 NA 20 1 0 1 1 1 1 1
## 741 NA 70 1 1 1 1 1 1 1
## Is.Alive Houses info
## 56 Alive Stark Arya Stark from House Stark is Alive
## 63 Alive Lannister Balon Swann from House Lannister is Alive
## 104 Alive Baratheon Boros Blount from House Baratheon is Alive
## 131 Alive Lannister Cersei Lannister from House Lannister is Alive
## 302 Alive Night's Watch Grenn from House Night's Watch is Alive
## 345 Alive Lannister Harys Swyft from House Lannister is Alive
## 383 Alive Lannister Jaime Lannister from House Lannister is Alive
## 410 Alive Night's Watch Jon Snow from House Night's Watch is Alive
## 436 Dead Lannister Kevan Lannister from House Lannister is Dead
## 452 Alive Lannister Lancel Lannister from House Lannister is Alive
## 548 Alive Lannister Meryn Trant from House Lannister is Alive
## 652 Dead Lannister Pycelle from House Lannister is Dead
## 741 Alive Night's Watch Samwell Tarly from House Night's Watch is Alive
#Еще
#heroes <- got[rowSums(got[, 9:13]) == 5, ]
- Создайте функцию
na_n()
, которая будет возвращать количествоNA
в векторе.
na_n <- function(x) sum(is.na(x))
na_n(c(NA, 3:5, NA, 2, NA))
## [1] 3
- Посчитайте количество NA в каждом столбце
got
.
apply(got, 2, na_n)
## Name Allegiances Death.Year
## 0 0 612
## Book.of.Death Death.Chapter Book.Intro.Chapter
## 610 618 12
## Gender Nobility GoT
## 0 0 0
## CoK SoS FfC
## 0 0 0
## DwD Is.Alive Houses
## 0 0 0
## info
## 0
- Есть список
spisok
:
spisok <- list(1:5, 0:20, 4:24, 6:3, 6:25)
- Посчитайте сумму каждого вектора.
sapply(spisok, sum)
## [1] 15 210 294 18 310
- А теперь длину.
sapply(spisok, length)
## [1] 5 21 21 4 20
- Напишите функцию
max_item()
, которая будет принимать на входе список, а возвращать - (первый) самый длинный его элемент.
max_item <- function (x) spisok[[which.max(sapply(x, length))]]
- Теперь мы сделаем сложный список:
large_spisok <- list(1:3, 3:40, spisok)
- Посчитайте длину каждого вектора в списке, в т.ч. для списка внутри
Для этого может понадобиться функция
rapply()
: recursive lapply
rapply(large_spisok, length, how = "list")
## [[1]]
## [1] 3
##
## [[2]]
## [1] 38
##
## [[3]]
## [[3]][[1]]
## [1] 5
##
## [[3]][[2]]
## [1] 21
##
## [[3]][[3]]
## [1] 21
##
## [[3]][[4]]
## [1] 4
##
## [[3]][[5]]
## [1] 20
6.9 Работа с текстом
Дан строковый вектор:
s <- c("Я", "выучу", "R", "за", "май!")
- Соедините вектор в одно строковое значение
ch
ch <- paste(s, collapse = " ")
ch
## [1] "Я выучу R за май!"
- Подсчитайте количество знаков в
ch
nchar(ch)
## [1] 17
- Следующее задание: вырезать Замая
substr(ch, 11, 16)
## [1] "за май"
- Превратите
ch
обратно в вектор, значения которого - отдельные слова:
strsplit(ch, " ")[[1]]
## [1] "Я" "выучу" "R" "за" "май!"
- Создайте дополнительную колонку в
got
под названиемinfo
, в которой будет написано: “ИМЯ_ПЕРСОНАЖА from House ЕГО_ДОМ is dead/alive” в зависимости от его статуса
got$info <- paste(got$Name, "from House", got$Houses, "is", got$Is.Alive)
got$info <- sprintf("%s from House %s is %s", got$Name, got$Houses, got$Is.Alive)
head(got$info)
## [1] "Addam Marbrand from House Lannister is Alive"
## [2] "Aegon Frey (Jinglebell) from House None is Dead"
## [3] "Aegon Targaryen from House Targaryen is Alive"
## [4] "Adrack Humble from House Greyjoy is Dead"
## [5] "Aemon Costayne from House Lannister is Alive"
## [6] "Aemon Estermont from House Baratheon is Alive"
- Посчитайте длину самого короткого имени в “Песни льда и пламени”?
min(nchar(got$Name))
## [1] 3
- На самом деле, функция
which.max()
выдает только индекс первого максимального значения, даже если их несколько. Это же верно для функцииwhich.min()
.
Напишите функцию which.all.min()
, которая выдает индексы всех минимальных значений векторов.
which.all.min <- function(x) (1:length(x))[x == min(x)]
Проверьте, что эта функция работает на длине имен персонажей:
got[which.all.min(nchar(got$Name)),]
## Name Allegiances Death.Year Book.of.Death Death.Chapter
## 81 Ben None NA NA NA
## 178 Del Wildling 299 3 41
## 352 Hod None NA NA NA
## 459 Lem None NA NA NA
## 467 Lew House Stark NA NA NA
## 590 Nan House Stark NA NA NA
## 602 Ogo None 298 1 61
## 640 Pia None NA NA NA
## 653 Pyg None 300 4 20
## 734 Ryk Wildling NA NA NA
## 850 Utt None 299 3 39
## 851 Val Wildling NA NA NA
## 912 Zei Stark NA NA NA
## Book.Intro.Chapter Gender Nobility GoT CoK SoS FfC DwD Is.Alive
## 81 37 1 0 0 0 0 1 0 Alive
## 178 41 1 0 0 0 1 0 0 Dead
## 352 5 1 0 0 1 0 0 0 Alive
## 459 13 1 0 0 0 1 1 0 Alive
## 467 7 1 0 1 0 0 0 0 Alive
## 590 1 0 0 1 1 0 0 0 Alive
## 602 46 1 1 1 0 0 0 0 Dead
## 640 30 0 0 0 1 0 1 0 Alive
## 653 20 1 0 0 0 1 1 0 Dead
## 734 7 1 0 0 0 1 0 0 Alive
## 850 30 1 0 0 1 1 0 0 Dead
## 851 7 0 0 0 0 1 0 1 Alive
## 912 64 0 0 0 0 1 0 0 Alive
## Houses info
## 81 None Ben from House None is Alive
## 178 Wildling Del from House Wildling is Dead
## 352 None Hod from House None is Alive
## 459 None Lem from House None is Alive
## 467 Stark Lew from House Stark is Alive
## 590 Stark Nan from House Stark is Alive
## 602 None Ogo from House None is Dead
## 640 None Pia from House None is Alive
## 653 None Pyg from House None is Dead
## 734 Wildling Ryk from House Wildling is Alive
## 850 None Utt from House None is Dead
## 851 Wildling Val from House Wildling is Alive
## 912 Stark Zei from House Stark is Alive
- Создайте функцию
is_anagram()
, которая будет выдаватьTRUE
если одно слово является анаграммой другого.
a <- "tree"
b <- "erte"
is_anagram <- function(a, b) paste(sort(strsplit(a, "")[[1]]), collapse = "") == paste(sort(strsplit(b, "")[[1]]), collapse = "")
Проверьте, работает ли функция, на двух векторах:
a <- c("спаниель", "капюшон", "state")
b <- c("апельсин", "парашют", "taste")
Нужно либо векторизовать функцию (сделать так, чтобы она могла принимать вектора на входе), либо использовать mapply(). Есть простой и хитрый способ векторизовать функцию - Vectorize(). Постарайтесь все-таки не использовать for, пожалуйста.
mapply(is_anagram, a, b)
## спаниель капюшон state
## TRUE FALSE TRUE
is_anagram_v <- function(a, b) {
sapply(sapply(sapply(a,strsplit, ""), sort), paste, collapse = "") == sapply(sapply(sapply(b,strsplit, ""), sort), paste, collapse = "")
}
6.10 data.table
Найдите все битвы, в которых attacker_king
- Robb Stark
.
batdt[attacker_king == "Robb Stark"]
## name year battle_number attacker_king
## 1: Battle of the Green Fork 298 4 Robb Stark
## 2: Battle of the Whispering Wood 298 5 Robb Stark
## 3: Battle of the Camps 298 6 Robb Stark
## 4: Battle of Torrhen's Square 299 11 Robb Stark
## 5: Battle of Oxcross 299 15 Robb Stark
## 6: Sack of Harrenhal 299 18 Robb Stark
## 7: Battle of the Crag 299 19 Robb Stark
## 8: Siege of Darry 299 21 Robb Stark
## 9: Battle of Duskendale 299 22 Robb Stark
## 10: Siege of Seagard 299 27 Robb Stark
## defender_king attacker_1 attacker_2 attacker_3 attacker_4
## 1: Joffrey/Tommen Baratheon Stark
## 2: Joffrey/Tommen Baratheon Stark Tully
## 3: Joffrey/Tommen Baratheon Stark Tully
## 4: Balon/Euron Greyjoy Stark
## 5: Joffrey/Tommen Baratheon Stark Tully
## 6: Joffrey/Tommen Baratheon Stark
## 7: Joffrey/Tommen Baratheon Stark
## 8: Joffrey/Tommen Baratheon Darry
## 9: Joffrey/Tommen Baratheon Stark
## 10: Joffrey/Tommen Baratheon Frey
## defender_1 defender_2 defender_3 defender_4 attacker_outcome
## 1: Lannister NA NA loss
## 2: Lannister NA NA win
## 3: Lannister NA NA win
## 4: Greyjoy NA NA win
## 5: Lannister NA NA win
## 6: Lannister NA NA win
## 7: Lannister NA NA win
## 8: Lannister NA NA win
## 9: Lannister NA NA loss
## 10: Mallister NA NA win
## battle_type major_death major_capture attacker_size defender_size
## 1: pitched battle 1 1 18000 20000
## 2: ambush 1 1 1875 6000
## 3: ambush 0 0 6000 12625
## 4: pitched battle 0 0 244 900
## 5: ambush 1 1 6000 10000
## 6: ambush 1 0 100 100
## 7: ambush 0 0 6000 NA
## 8: siege 0 0 NA NA
## 9: pitched battle 1 0 3000 NA
## 10: siege 0 1 NA NA
## attacker_commander
## 1: Roose Bolton, Wylis Manderly, Medger Cerwyn, Harrion Karstark, Halys Hornwood
## 2: Robb Stark, Brynden Tully
## 3: Robb Stark, Tytos Blackwood, Brynden Tully
## 4: Rodrik Cassel, Cley Cerwyn
## 5: Robb Stark, Brynden Tully
## 6: Roose Bolton, Vargo Hoat, Robett Glover
## 7: Robb Stark, Smalljon Umber, Black Walder Frey
## 8: Helman Tallhart
## 9: Robertt Glover, Helman Tallhart
## 10: Walder Frey
## defender_commander
## 1: Tywin Lannister, Gregor Clegane, Kevan Lannister, Addam Marbrand
## 2: Jaime Lannister
## 3: Lord Andros Brax, Forley Prester
## 4: Dagmer Cleftjaw
## 5: Stafford Lannister, Roland Crakehall, Antario Jast
## 6: Amory Lorch
## 7: Rolph Spicer
## 8:
## 9: Randyll Tarly, Gregor Clegane
## 10: Jason Mallister
## summer location region
## 1: 1 Green Fork The Riverlands
## 2: 1 Whispering Wood The Riverlands
## 3: 1 Riverrun The Riverlands
## 4: 1 Torrhen's Square The North
## 5: 1 Oxcross The Westerlands
## 6: 1 Harrenhal The Riverlands
## 7: 1 Crag The Westerlands
## 8: 1 Darry The Riverlands
## 9: 1 Duskendale The Crownlands
## 10: 1 Seagard The Riverlands
## note
## 1:
## 2:
## 3:
## 4: Greyjoy's troop number comes from the 264 estimate to have arrived on the stony shore minus the 20 Theon takes to attack Winterfell. Thus 264-20=244
## 5:
## 6:
## 7:
## 8:
## 9:
## 10:
## outcome all_army ratio_army
## 1: Победа защищающихся 38000 0.9000000
## 2: Победа атакующих 7875 0.3125000
## 3: Победа атакующих 18625 0.4752475
## 4: Победа атакующих 1144 0.2711111
## 5: Победа атакующих 16000 0.6000000
## 6: Победа атакующих 200 1.0000000
## 7: Победа атакующих NA NA
## 8: Победа атакующих NA NA
## 9: Победа защищающихся NA NA
## 10: Победа атакующих NA NA
Как они заканчивались?
batdt[attacker_king == "Robb Stark", .N, by = attacker_outcome]
## attacker_outcome N
## 1: loss 2
## 2: win 8
Найдите, в битвах какого типа проигрывал Robb Stark
как атакующий король.
batdt[attacker_king == "Robb Stark", .N, by = .(attacker_outcome, battle_type)]
## attacker_outcome battle_type N
## 1: loss pitched battle 2
## 2: win ambush 5
## 3: win pitched battle 1
## 4: win siege 2
6.11 Решейпинг
- Допустим, у вас есть следующий
data.table
:
iq <- data.table(id = 1:3, iq_before = c(98, 106, 102), iq_after = c(103, 105, 103))
- Превратите широкий iq в длинный iq_long с колонками
id
,time
,IQ
iq_long <- melt(iq, id.vars = 'id', variable.name = "time", value.name = "IQ")
iq_long
## id time IQ
## 1: 1 iq_before 98
## 2: 2 iq_before 106
## 3: 3 iq_before 102
## 4: 1 iq_after 103
## 5: 2 iq_after 105
## 6: 3 iq_after 103
- В колонке
time
должно быть значениеbefore
илиafter
iq_long[, time := gsub("iq_", "", time)]
iq_long
## id time IQ
## 1: 1 before 98
## 2: 2 before 106
## 3: 3 before 102
## 4: 1 after 103
## 5: 2 after 105
## 6: 3 after 103
- А теперь обратно
iq_long
в широкий формат:
dcast(iq_long, ... ~ time)
## id after before
## 1: 1 103 98
## 2: 2 105 106
## 3: 3 103 102
6.12 Описательная статистика
Вспомните все описательные статистики, которые мы прошли, и примените их на векторе
pbcdt$chol
(количество холистерина). Попытайтесь представить, как будут распределены эти данные исходя из результатов.Посчитайте описательные статистики
Создайте функцию
check_outliers()
, которая принимает как аргумент числовой вектор, а возвращает логический вектор:TRUE
- если есть значения больше или меньше чем 3 стандартных отклонения от среднего,FALSE
в обратнос случае. Проверьте функцию на вектореpbcdt$chol
. Посчитайте количествоTRUE
в результате.
check_outliers <- function(x) abs(x - mean(x))>3*sd(x)
sum(check_outliers(pbcdt$chol))
## [1] 8
- Измените функцию
check_outliers()
, чтобы у нее появился параметрn =
со значением 3 по умолчанию. От этого параметра должно зависеть количество стандартных отклонений от среднего в формуле. Проверьте функцию на том же векторе иn = 2
:
check_outliers <- function(x, n) abs(x - mean(x))>n*sd(x)
sum(check_outliers(pbcdt$chol, n = 2))
## [1] 13
- Добавим в функцию
check_outliers()
еще больше гибкости. Теперь функция сможет принимать на вход еще и функции центральной тенденции и вариабельностиcentral =
иdeviation =
со средним и стандартным отклонением по умолчанию. Проверьте функцию с помощьюn = 3
, медианой и медианным абсолютным отклонением.
check_outliers <- function(x, n, central = mean, deviation = sd) abs(x - central(x))>n*deviation(x)
sum(check_outliers(pbcdt$chol, n = 3, median, mad))
## [1] 20
- \[s^2_{pool} = \frac {(n_1-1)s^2_1 + (n_2-1)s^2_2} {(n_1 - 1) + (n_2 -1)}\]