- Представить данные в длинном формате с правильным обозначением перменных и пропущенных значений
- Построить простейшие статистические графики с использованием функций из пакета ggplot2
- Настраивать параметры графиков
На подготовку данных к анализу уходит до 80% времени.
Существуют определенные правила предоставления данных.
Данные, построенные в соответствии с этими требованиями, называются tidy data, или опрятные данные.
NA
)При работе в Excel не должно быть никаких объединенных ячеек!
В среде R
создано несколько удобных пакетов для преобразования данных:
reshape2
dplyr
tidyr
Мы постепенно научимся ими пользоваться
Широкий формат: данные максимально структурированы, каждая строка может нести информацию о многих элементарных объектах
Длинный формат: данные минимально структурированы, каждая строка характеризует уникальный объект
Из длинного формата легко получить широкий.
Из широкого формата получить длинный заметно сложнее.
Широкий формат хорош для отчетов, представления обобщенных результатов
Длинный формат хорош для анализа
titanic <- read.table('data/Titanic.csv', sep = ';', header = TRUE)
head(titanic, 8)
## Class Sex Age Survived Freq ## 1 1st Male Child No 0 ## 2 2nd Male Child No 0 ## 3 3rd Male Child No 35 ## 4 Crew Male Child No 0 ## 5 1st Female Child No 0 ## 6 2nd Female Child No 0 ## 7 3rd Female Child No 17 ## 8 Crew Female Child No 0
library(tidyr) long_titanic <- uncount(titanic, weights = Freq) head(long_titanic, 10)
## Class Sex Age Survived ## 1 3rd Male Child No ## 2 3rd Male Child No ## 3 3rd Male Child No ## 4 3rd Male Child No ## 5 3rd Male Child No ## 6 3rd Male Child No ## 7 3rd Male Child No ## 8 3rd Male Child No ## 9 3rd Male Child No ## 10 3rd Male Child No
Данные взяты из работы
Tager, I. B., Weiss, S. T., Rosner, B., and Speizer, F. E. (1979). Effect of parental cigarette smoking on pulmonary function in children. American Journal of Epidemiology, 110, 15-26.
Источник данных: [http://www.statsci.org/data/general/fev.html]
Структура данных:
Age
— ВозрастFEV
— Объем легких при выдохе (литры) (forced expiratory volume)Height
— Рост (дюймы)Sex
— пол (Male or Female)Smoker
— некурящие (Non), курящие (Current)
library(readxl) fev <- read_excel("data/fev.xls", sheet = "tidy_data", col_names = TRUE, na = "NA", skip = 1 )
Имена переменных
names(fev)
## [1] "Age" "FEV" "Height" "Sex" "Smoker"
Содержание переменных
str(fev)
## tibble [654 x 5] (S3: tbl_df/tbl/data.frame) ## $ Age : num [1:654] 9 8 7 9 9 8 6 6 8 9 ... ## $ FEV : num [1:654] 1.71 1.72 1.72 1.56 1.9 ... ## $ Height: num [1:654] 57 67.5 54.5 53 57 61 58 56 58.5 60 ... ## $ Sex : chr [1:654] "Female" "Female" "Female" "Male" ... ## $ Smoker: chr [1:654] "Non" "Non" "Non" "Non" ...
Необходимо заменить формат в переменных fev$Sex
и fev$Smoker
fev$Sex <- factor(fev$Sex) fev$Smoker <- factor(fev$Smoker)
функция factor()
превращает числовые или текстовые данные в дискретные факторы
NA
Если необходимо убрать объекты, у которых что-то не измерено (NA), то надо произвести “очистку данных”.
НО! не увлекайтесь, иногда можно “вычистить”” важную информацию
В каких строках содержится пропущенная информация?
fev[which(!complete.cases(fev)), ]
## # A tibble: 2 x 5 ## Age FEV Height Sex Smoker ## <dbl> <dbl> <dbl> <fct> <fct> ## 1 16 4.50 72 Male <NA> ## 2 NA 3.21 66.5 Female Non
здесь используется сразу две функции: which()
, в нее вложена complete.cases()
! - логическая операция “NOT”
[ , ] - оператор индексации на первом месте строка, на втором - столбец
fev <- fev[complete.cases(fev), ]
Название пакета происходит от слов “Grammar”, “Graphics”, “Plot”.
В основе подхода, реализованного в пакете, лежит идея грамматики графиков “Semiology of Graphics” (Bertin, 1983).
Более позднее обобщение “The Grammar of Graphics” (Wilkinson, Anand and Grossman, 2005).
Задача: построить точечную диаграмму, где по оси OX отложен Age, а по оси OY отложен FEV
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point()
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point() + theme_bw()
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point() + theme_classic()
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point() + theme_minimal()
theme_set(theme_bw())
далее все графики, производимые в данной сессии, будут использовать именно эту тему
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point()
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point() + labs(x = "Возраст", y = "Объем легких")
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point() + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких")
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point() + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких") + theme(plot.title = element_text(hjust = 0.5))
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point(size = 3) + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких") + theme(plot.title = element_text(hjust = 0.5))
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point(size = 0.1) + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких") + theme(plot.title = element_text(hjust = 0.5))
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point(color = "blue") + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких") + theme(plot.title = element_text(hjust = 0.5))
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point(shape = 22, color = "red", fill = "yellow", size = 2) + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких") + theme(plot.title = element_text(hjust = 0.5))
Создаем рисунок
ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point(shape = 22, color = "red", fill = "yellow", size = 2) + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких") + theme(plot.title = element_text(hjust = 0.5))
Сохраняем текущий рисунок в файл
ggsave("MyPicture.wmf", plot = last_plot())
Рисунок можно, и это правильно, поместить в специальную переменную
Plot_1 <- ggplot(data = fev, aes(x = Age, y = FEV)) + geom_point(shape = 22, color = "red", fill = "yellow", size = 2) Plot_1
Plot_1 + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких") + theme(plot.title = element_text(hjust = 0.5))
Plot_2 <- Plot_1 + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких") + theme(plot.title = element_text(hjust = 0.5)) ggsave("MyPicture_2.wmf", plot = Plot_2)
В философии ggplot эстетики - это та информация (данные), которую можно выразить графиком.
Минимальные эстетики - Положение на OX и положение на OY
Однако наши данные содержат еще и информацию о поле (переменная fev$Sex
). Если эти данные для нас важны, то мы должны эту информацию выразить на графике
Plot_1 <- ggplot(data = fev, aes(x = Age, y = FEV, color = Sex )) + geom_point(size = 2) + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких") + theme(plot.title = element_text(hjust = 0.5)) Plot_1
Plot_1 <- Plot_1 + scale_color_manual(values = c("pink","blue")) Plot_1
Plot_1 + theme(legend.position = "bottom")
Plot_1 + theme(legend.position = "left")
Plot_1 + theme(legend.position = c(0.1, 0.9))
c(0.1, 0.9)
координаты указываются в долях от сторон рисунка
Plot_1 <- ggplot(data = fev, aes(x = Age, y = FEV, shape = Sex, color = Sex )) + geom_point(size = 2) + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких") + theme(plot.title = element_text(hjust = 0.5)) Plot_1
Если мы хотим выразить графиком одновременно данные по полу и по курению, то мы должны задать две разные эстетики
Plot_1 <- ggplot(data = fev, aes(x = Age, y = FEV, shape = Sex, color = Smoker )) + geom_point(size = 2) + labs(x = "Возраст", y = "Объем легких", title = "Зависимость между \n возрастом и объемом легких") + theme(plot.title = element_text(hjust = 0.5)) Plot_1
в этом трудно разобраться
Plot_1 + facet_wrap( ~ Smoker) #уже лучше
Plot_1 + facet_grid(Sex ~ Smoker)
Геомы - это геометрические объекты, которые отражают данные (точки, линии, столбцы, “усы” и т. д.)
Задание: построить гистограмму, отражающую частотное распределение объема легких
Для решений этой задачи не годится применение точечных диаграмм
Нам нужен другой геом
ggplot(fev, aes(x = FEV)) + geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Делаем более широкие классовые интервалы
ggplot(fev, aes(x = FEV)) + geom_histogram(binwidth = 1)
Делаем более узкие классовые интервалы
ggplot(fev, aes(x = FEV)) + geom_histogram(binwidth = 0.1)
stat
Поскольку в основе построения гистограммы лежит статистическая процедура (определение частот), то все тоже самое можно сделать с помощью функций stat_…
ggplot(fev, aes(x = FEV)) + stat_bin(geom = "bar") #Аналогично!
ggplot(fev, aes(x = FEV)) + stat_bin(geom = "bar", binwidth = 0.1)
Аналогично применению geom_histogram(binwidth = 0.1)
ggplot(fev, aes(x = FEV)) + stat_bin(geom = "line", size = 1, color = "red")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
ggplot(fev, aes(x = FEV)) + stat_bin(geom = "area", size = 1, color = "red")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Например, так
ggplot(fev, aes(x = FEV)) + stat_density(geom = "area", size = 1, color = "red", fill = "blue")
ggplot(fev, aes(x = FEV)) + geom_histogram() + facet_wrap( ~ Sex)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
ggplot(fev, aes(x = FEV)) + geom_histogram() + facet_wrap( ~ Sex, ncol = 1)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
ggplot(fev, aes(x = FEV, fill = Smoker)) + geom_histogram() + facet_wrap( ~ Sex, ncol = 1)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Трудно читать
ggplot(fev, aes(x = FEV, fill = Smoker)) + stat_density(geom = "area", size = 1, color = "red") + facet_wrap( ~ Sex, ncol = 1)
ggplot(fev, aes(x = Age, y = FEV)) + stat_summary(fun.y = "mean", geom = "line", size = 2)
ggplot(fev, aes(x = Age, y = FEV, color = Sex)) + stat_summary(fun.y = "mean", geom = "line", size = 2)
ggplot(fev, aes(x = Age, y = FEV, color = Sex)) + stat_summary(fun.y = "mean", geom = "line", size = 2) + facet_wrap( ~ Smoker)
ggplot(fev, aes(x = Sex, y = Height, fill = Sex)) + stat_summary(fun.y = "mean", geom = "bar")
ggplot(fev, aes(x = Age, y = FEV, color = Smoker)) + geom_point() + geom_smooth(method = "lm") + facet_wrap( ~ Sex)
## `geom_smooth()` using formula 'y ~ x'