Часть 1

Задача 1.

В двух переменных сохранены некоторые значения:

x <- 2
y <- 4

Напишите код, который позволит поменять значения в переменных x и y местами, то есть получить следующее:

x
## [1] 2
y
## [1] 4

Внимание: Ваш код должен работать для любых значений x, y.

# вариант 1

z <- y # сохраним значение y в новую переменную z
y <- x # запишем значение x в y
x <- z # запишем значение z (бывшее y) в x
# вариант 2

z <- x # сохраним значение x в новую переменную z
x <- y # запишем значение y в x
y <- z # запишем значение z (бывшее x) в y

Полезная аналогия: представьте, что у нас есть две коробки, и мы хотим переложить содержимое первой коробки во вторую, а содержимое второй – в первую. Чтобы это сделать, мы должны сначала содержимое одной из коробок куда-то выложить. Так же и с переменными: создаем переменную z в качестве временного хранилища значений.

Задача 2.

x <- 3.5
y <- "2,6"
z <- 1.78
h <- TRUE

Определите типы переменных:

class(x)
## [1] "numeric"
class(y)
## [1] "character"
class(z)
## [1] "numeric"
class(h)
## [1] "logical"

Сделайте переменную h целочисленной.

h <- as.integer(h)

Сделайте переменную y числовой (обратите внимание на запятую!).

y <- gsub(",", ".", y) # заменяем запятую на точку
y <- as.numeric(y)

Сделайте переменную x текстовой.

x <- as.character(x)

Задача 3.

Исследователь сохранил доход респондента в переменную dohod:

dohod <- 1573

Исследователь передумал и решил изменить значение этой переменной - сохранить в нее натуральный логарифм дохода. Помогите ему!

dohod <- log(dohod)

Часть 2

** Задача 1.**

Дан вектор g, в котором хранятся следующие значения:

1, 0, 2, 3, 6, 8, 12, 15, 0, NA, NA, 9, 4, 16, 2, 0

g <- c(1, 0, 2, 3, 6, 8, 12, 15, 0, NA, NA, 9, 4, 16, 2, 0)

Выведите на экран:

g[1]
## [1] 1
g[length(g)]
## [1] 0
g[3:5]
## [1] 2 3 6
g[g == 2] # для NA выполняются ЛЮБЫЕ условия
## [1]  2 NA NA  2
g[g > 4]
## [1]  6  8 12 15 NA NA  9 16
g[g %% 3 == 0]
##  [1]  0  3  6 12 15  0 NA NA  9  0
# напоминание про %% - остаток от деления
# остаток от деления 15 на 2 равен 1
15 %% 2
## [1] 1
g[g > 4 & g %% 3 == 0]
## [1]  6 12 15 NA NA  9
g[g < 1 | g > 5]
##  [1]  0  6  8 12 15  0 NA NA  9 16  0
which(g == 0)
## [1]  2  9 16
which(g >= 2 & g <= 8)
## [1]  3  4  5  6 13 15

Как убрать NA:

# ! - отрицание
g <- g[! is.na(g)]

Задача 2.

Напишите код, который заменяет последний элемент вектора на пропущенное значение (NA). Ваш код должен работать для любого вектора (любой длины).

v <- c(1, 9, 3, 4)
v[length(v)] <- NA

Задача 3.

Напишите код, который выводит на экран индексы пропущенных значений в векторе.

w <- c(0, 1, NA, NA)
which(is.na(w)) 
## [1] 3 4

Задача 4.

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

sum(is.na(w))
## [1] 2

Задача 5.

Напишите код, который позволяет создать вектор из id (уникальных номеров) респондентов, если известно, что в опросе участвовало 100 респондентов.

id <- 1:100

Задача 6.

Известно, что в базе данных хранятся показатели по 3 странам за 5 лет. Таблица выглядит примерно так:

[страшный html-код для таблицы]

country year
1 France 2000
2 France 2001
3 France 2002
4 France 2003
5 France 2004
6 Italy 2000
7 Italy 2001
8 Italy 2002
9 Italy 2003
10 Italy 2004
11 Spain 2000
12 Spain 2001
13 Spain 2002
14 Spain 2003
15 Spain 2004
cnt <- rep(c("France", "Italy", "Spain"), each = 5) # столбец country
year <- rep(2000:2004, 3) # столбец year

Дополнение: как бы мы объединили эти векторы в датафрейм (таблицу)? Воспользовались бы функцией cbind.data.frame():

dat <- cbind.data.frame(cnt, year)
View(dat)

Почему не просто cbind()? Потому что cbind() возвращает матрицу, а матрица может состоять только из элементов одного типа. Здесь столбец со странами должен быть текстовым, а столбец с годами – числовым.

Задача 7.

Исследователю из задачи 3 из части 1 понравилось, как Вы работаете в R, и теперь он решил создать вектор income, в котором сохранены доходы нескольких респондентов:

income <- c(10000, 32000, 28000, 150000, 65000, 1573)

Исследователю нужно получить вектор income_class, состоящий из 0 и 1: 0 ставится, если доход респондента ниже среднего дохода, а 1 - если больше или равен среднему доходу.

Подсказка: сначала можно посчитать среднее значение по вектору income и сохранить его в какую-нибудь переменную. Пользоваться встроенной функцией mean() нельзя.

ave_income <- sum(income) / length(income)
income_class <- as.integer(income >= ave_income)
income_class
## [1] 0 0 0 1 1 0

Часть 3

Задача 1.

Создайте матрицу размерности 3 * 4, состоящую из 3, а затем измените некоторые ее элементы так, чтобы получить следующее:

[3 3 4 3]
[1 3 3 3]
[3 NA 3 1]
M <- matrix(3, nrow = 3, ncol = 4)
M
##      [,1] [,2] [,3] [,4]
## [1,]    3    3    3    3
## [2,]    3    3    3    3
## [3,]    3    3    3    3

Заменяем:

M[1, 3] <- 4
M[2, 1] <- 1
M[3, 2] <- NA
M[3, 4] <- 1
M
##      [,1] [,2] [,3] [,4]
## [1,]    3    3    4    3
## [2,]    1    3    3    3
## [3,]    3   NA    3    1

Задача 2.

Создайте из следующих векторов матрицу, такую, что:

a <- c(1, 3, 4, 9, NA)
b <- c(5, 6, 7, 0, 2)
c <- c(9, 10, 13, 1, 20)
# столбцами
mat1 <- cbind(a, b, c)
mat1
##       a b  c
## [1,]  1 5  9
## [2,]  3 6 10
## [3,]  4 7 13
## [4,]  9 0  1
## [5,] NA 2 20
# строками
mat2 <- rbind(a, b, c)
mat2
##   [,1] [,2] [,3] [,4] [,5]
## a    1    3    4    9   NA
## b    5    6    7    0    2
## c    9   10   13    1   20

Дайте (новые) названия строкам и столбцам матрицы.

# теперь, когда знаем про списки, 
# можем позволить себе присвоить 
# названия столбцам и строкам одновременно

dimnames(mat2) <- list(c("r1", "r2", "r3"), LETTERS[1:5])

Задача 3.

Может ли матрица состоять из элементов разных типов? Проверьте: составьте матрицу из следующих векторов (по столбцам):

names <- c("Jane", "Michael", "Mary", "George")
ages <- c(8, 6, 28, 45)
gender <- c(0, 1, 0, 1)
# не может!
# все превращается в текст!

cbind(names, ages, gender)
##      names     ages gender
## [1,] "Jane"    "8"  "0"   
## [2,] "Michael" "6"  "1"   
## [3,] "Mary"    "28" "0"   
## [4,] "George"  "45" "1"

Если получилось не то, что хотелось, подумайте, как это можно исправить, не теряя информации, которая сохранена в векторах.

# можно, конечно, вспомнить про cbind.data.frame()
# но результат уже будет data.frame, не matrix
# поэтому просто сделаем names названиями строк

mym <- cbind(ages, gender)
rownames(mym) <- names
mym
##         ages gender
## Jane       8      0
## Michael    6      1
## Mary      28      0
## George    45      1

Добавьте в матрицу столбец age_sq – возраст в квадрате.

age_sq <- ages ** 2
mym <- cbind(mym, age_sq) # склеиваем матрицу и столбец
mym
##         ages gender age_sq
## Jane       8      0     64
## Michael    6      1     36
## Mary      28      0    784
## George    45      1   2025

Задачи 4-5 остались на следующий семинар.