Студенты думают, что .csv файлы как булки на деревьях растут!

Новички даже не предполагают, сколько времени занимает предварительная обработка данных! Удаление явно ошибочных значений, приведение к нужному формату, слияние данных из нескольких источников и прочие “мелочи”.

Загружаем нужные библиотеки:

library("knitr")

library("dplyr") # стратегия Разделяй - Властвуй - Соединяй
library("reshape2") # melt - cast
library("ggplot2") # графики

Создание выборок …

Разделяй и властвуй! Затем соединяй!

Многие преобразования могут быть описаны с помощью принципа “Разделяй и властвуй! Затем соединяй!”:

Загрузим данные по стоимости квартир в Москве:

filename <- "../datasets/flats_moscow.txt"
flats <- read.table(filename, header = TRUE)

Пример. Подсчёт описательных статистик внутри групп

Мы разбиваем большую таблицу на маленькие таблички по переменным code (географический район квартиры) и brick (кирпичность). По каждой маленькой табличке считаем число наблюдений и среднюю цену квартиры. Затем сводим в итоговую таблицу:

flats_summ <- flats %>% group_by(code, brick) %>%
  summarize(n = n(), mean = mean(price))

head(flats_summ)
## Source: local data frame [6 x 4]
## Groups: code [3]
## 
##    code brick     n     mean
##   (int) (int) (int)    (dbl)
## 1     1     0   180 123.0000
## 2     1     1    92 156.7391
## 3     2     0   186 105.9516
## 4     2     1    29 138.3103
## 5     3     0   169 134.7337
## 6     3     1   176 161.2216

Пример. Корректировка наблюдения на групповое среднее.

Из цены каждой квартиры будет вычтена средняя цена по квартирам данного района и данной кирпичности.

flats_new <- flats %>% group_by(code, brick) %>%
  mutate(delta = price - mean(price))

head(flats_new)
## Source: local data frame [6 x 12]
## Groups: code, brick [4]
## 
##       n price totsp livesp kitsp  dist metrdist  walk brick floor  code
##   (int) (int) (int)  (int) (dbl) (dbl)    (int) (int) (int) (int) (int)
## 1     1    81    58     40     6  12.5        7     1     1     1     3
## 2     2    75    44     28     6  13.5        7     1     0     1     6
## 3     3   128    70     42     6  14.5        3     1     1     1     3
## 4     4    95    61     37     6  13.5        7     1     0     1     1
## 5     5   330   104     60    11  10.5        7     0     1     1     3
## 6     6   137    76     50     9  11.0        7     1     1     1     8
## Variables not shown: delta (dbl)

Итого:

Отбор самых-самых наблюдений

Длинная и широкая

Теорема о крокодиле. Крокодил более широкий чем длинный.

Доказательство.

Шаг 1. Крокодил более широкий, чем зеленый. Зеленый он только снаружи, а широкий он и снаружи и внутри.

Шаг 2. Крокодил более зеленый, чем длинный. Зеленый он и в длину, и в ширину, а длинный - только в длину.

Шаг 3. Отношение “больше” транзитивно :)

Упражнение. Докажите, что крокодил более длинный, чем широкий.

Упражнение. Докажите, что крокодилов не существует.

Таблицы данных бывают “широкие” и “длинные”.

Пример “широкой” таблицы:

tab_wide <- smiths

head(tab_wide)
##      subject time age weight height
## 1 John Smith    1  33     90   1.87
## 2 Mary Smith    1  NA     NA   1.54

Пример “длинной” таблицы:

names(airquality) <- tolower(names(airquality))
tab_long <- melt(airquality, id = c("month", "day"), na.rm = TRUE)

head(tab_long)
##   month day variable value
## 1     5   1    ozone    41
## 2     5   2    ozone    36
## 3     5   3    ozone    12
## 4     5   4    ozone    18
## 6     5   6    ozone    28
## 7     5   7    ozone    23

Данные удобнее обрабатывать в “длинном” формате. В “длинном” формате при получении новых наблюдений не нужно добавлять столбцы в data.frame. “Широкий” формат изредка бывает удобен для представления результатов. Или клиент так хочет.

Чтобы табличка растаяла из “широкого” формата и стекла вниз в “длинный” её можно растопить командой melt из пакета reshape:

tab_long2 <- melt(tab_wide, id = "subject")

head(tab_long2)
##      subject variable value
## 1 John Smith     time     1
## 2 Mary Smith     time     1
## 3 John Smith      age    33
## 4 Mary Smith      age    NA
## 5 John Smith   weight    90
## 6 Mary Smith   weight    NA

Обратное действие выполняется командой dcast:

tab_wide2 <- dcast(tab_long, day + month ~ variable)
head(tab_wide2)
##   day month ozone solar.r wind temp
## 1   1     5    41     190  7.4   67
## 2   1     6    NA     286  8.6   78
## 3   1     7   135     269  4.1   84
## 4   1     8    39      83  6.9   81
## 5   1     9    96     167  6.9   91
## 6   2     5    36     118  8.0   72

Слияние данных из разных источников

# merge

Векторизация функций

Если операция, которую нужно выполнить очень сложная, то можно сделать её в три шага:

Этот подход, конечно, можно комбинировать с использованием стратегии Разделяй-Властвуй-Соединяй.