class: center, middle, inverse, title-slide # Язык R и его применение в биоинформатике ### Анна Валяева ### 23.09.2021 --- # Чтение файла - {readr} <style> html { padding: unset;} body { padding: unset;} </style> ```r library(readr) # или library(tidyverse) ``` - `read_csv()` - `read_tsv()` - `read_delim()` Нужно указать путь до файла на компьютере или адрес файла в Сети: ```r penguins <- read_csv("data/penguins.csv") penguins <- read_csv("https://raw.githubusercontent.com/kirushka/datasets/main/penguins.csv") ``` --- # Чтение файла ```r penguins <- read_csv("data/penguins.csv") penguins ``` ``` # A tibble: 344 x 8 species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g <chr> <chr> <dbl> <dbl> <dbl> <dbl> 1 Adelie Torgersen 39.1 18.7 181 3750 2 Adelie Torgersen 39.5 17.4 186 3800 3 Adelie Torgersen 40.3 18 195 3250 4 Adelie Torgersen NA NA NA NA 5 Adelie Torgersen 36.7 19.3 193 3450 6 Adelie Torgersen 39.3 20.6 190 3650 7 Adelie Torgersen 38.9 17.8 181 3625 8 Adelie Torgersen 39.2 19.6 195 4675 9 Adelie Torgersen 34.1 18.1 193 3475 10 Adelie Torgersen 42 20.2 190 4250 # ... with 334 more rows, and 2 more variables: sex <chr>, year <dbl> ``` --- # Датасет про пингвинов - {palmerpenguins} <img src="data:image/png;base64,#https://allisonhorst.github.io/palmerpenguins/reference/figures/lter_penguins.png" width="80%" style="display: block; margin: auto;" /> *Artwork by @allison_horst* --- # Чтение файла Посмотреть все параметры: `?read_csv`. <img src="data:image/png;base64,#img/readr/readr_read_params.PNG" width="80%" style="display: block; margin: auto;" /> --- # Запись в файл Посмотреть все параметры: `?write_csv`. ```r write_csv(penguins[1:2,], "some_penguins.csv") write_csv( penguins[3:10,], "some_penguins.csv", append = TRUE) ``` --- # Чтение Excel файла - {readxl} ```r library(readxl) # Прочитать первый лист в файле df1 <- read_excel("data/some_data.xlsx") # Прочитать лист с названием "Second_sheet" df2 <- read_excel( "data/some_data.xlsx", sheet = "Second_sheet") ``` --- # Графика ```r plot( body_mass_g ~ flipper_length_mm, col = factor(species), data = penguins, xlab = "Flipper length (mm)", ylab = "Body mass (g)", main = "Penguin size") ``` <img src="data:image/png;base64,#figs/plot_scatter-1.png" width="80%" style="display: block; margin: auto;" /> --- # Гистограмма ```r hist(penguins$body_mass_g) ``` <img src="data:image/png;base64,#figs/plot_hist-1.png" width="80%" style="display: block; margin: auto;" /> --- # Графика {ggplot2} ```r ggplot( data = <DATA>, mapping = aes(<MAPPINGS>)) + <GEOM_FUNCTION>() + ... ``` <img src="data:image/png;base64,#img/ggplot2/ggplot_layers.png" width="60%" style="display: block; margin: auto;" /> --- count: false # Данные -> оси -> тип графика -> ... .panel1-ggplot_basics-user[ ```r *ggplot(penguins) ``` ] .panel2-ggplot_basics-user[ <img src="data:image/png;base64,#figs/ggplot_basics_user_01_output-1.png" width="80%" style="display: block; margin: auto;" /> ] --- count: false # Данные -> оси -> тип графика -> ... .panel1-ggplot_basics-user[ ```r ggplot(penguins) + * aes( * x = bill_length_mm, * y = bill_depth_mm, * color = species) ``` ] .panel2-ggplot_basics-user[ <img src="data:image/png;base64,#figs/ggplot_basics_user_02_output-1.png" width="80%" style="display: block; margin: auto;" /> ] --- count: false # Данные -> оси -> тип графика -> ... .panel1-ggplot_basics-user[ ```r ggplot(penguins) + aes( x = bill_length_mm, y = bill_depth_mm, color = species) + * geom_point( * size = 3, * alpha = 0.8) ``` ] .panel2-ggplot_basics-user[ <img src="data:image/png;base64,#figs/ggplot_basics_user_03_output-1.png" width="80%" style="display: block; margin: auto;" /> ] --- count: false # Данные -> оси -> тип графика -> ... .panel1-ggplot_basics-user[ ```r ggplot(penguins) + aes( x = bill_length_mm, y = bill_depth_mm, color = species) + geom_point( size = 3, alpha = 0.8) + * theme_bw() ``` ] .panel2-ggplot_basics-user[ <img src="data:image/png;base64,#figs/ggplot_basics_user_04_output-1.png" width="80%" style="display: block; margin: auto;" /> ] <style> .panel1-ggplot_basics-user { color: black; width: 38.6060606060606%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel2-ggplot_basics-user { color: black; width: 59.3939393939394%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel3-ggplot_basics-user { color: black; width: NA%; hight: 33%; float: left; padding-left: 1%; font-size: 80% } </style> --- # ggplot2 <br> <br> <img src="data:image/png;base64,#img/ggplot2/ggplot2_scheme.PNG" width="90%" style="display: block; margin: auto;" /> --- # Варианты `aes` - aesthetic .pull-left[ ### Для geom_point() - `shape` - тип символа - `color` - цвет общий / цвет обводки - `fill` - заливка - `size` - размер - `stroke` - толщина обводки - `alpha` - прозрачность ] .pull-right[ <img src="data:image/png;base64,#img/ggplot2/point_shape.png" width="100%" style="display: block; margin: auto;" /> ] [Cheat sheets](https://ggplot2tor.com/cheatsheets/) --- # Запишем кусок графика в переменную ```r p <- ggplot(penguins, aes(x = bill_length_mm, y = bill_depth_mm)) + theme_bw() p + geom_point(size = 3, alpha = 0.8) ``` <img src="data:image/png;base64,#figs/ggplot_var-1.png" width="80%" style="display: block; margin: auto;" /> --- .pull-left[ Только `color`, определяет цвет всей фигуры - кружочка. ```r p + theme(legend.position = "top") + * geom_point(aes(color = species), shape = 16) ``` <img src="data:image/png;base64,#figs/point_shape_fill-1.png" width="100%" style="display: block; margin: auto;" /> ] .pull-right[ Только `color`, определяет цвет всей фигуры - окружности. ```r p + theme(legend.position = "top") + * geom_point(aes(color = species), shape = 1) ``` <img src="data:image/png;base64,#figs/point_shape_col-1.png" width="100%" style="display: block; margin: auto;" /> ] --- И `color`, и `fill` для обводки и заливки. ```r p + * geom_point(aes(fill = species, color = island), shape = 21) ``` <img src="data:image/png;base64,#figs/point_shape_col_fill-1.png" width="80%" style="display: block; margin: auto;" /> --- # Константа *vs* переменная .pull-left[ ```r p + * geom_point(color = "#2a9d8f") ``` <img src="data:image/png;base64,#figs/ggplot_aes_const-1.png" width="80%" style="display: block; margin: auto;" /> ] .pull-right[ ```r p + * geom_point(aes(color = species)) ``` <img src="data:image/png;base64,#figs/ggplot_aes_var-1.png" width="80%" style="display: block; margin: auto;" /> ] --- # Цветовая шкала ```r cols <- c("#00afb9", "#fed9b7", "#f07167") p_labels <- c("Адели", "Антарктический", "Субантарктический") p <- p + geom_point(aes(color = species), size = 3, alpha = 0.8) + * scale_color_manual(values = cols, labels = p_labels) p ``` <img src="data:image/png;base64,#figs/ggplot_color_scale-1.png" width="80%" style="display: block; margin: auto;" /> --- # Цветовая шкала - Использовать стандартную палитру **{ggplot2}** - Задать цвет вручную: `"red"/"#f07167"` - Сочетающиеся цвета можно искать на [coolors.co](https://coolors.co/), ... - Использовать специальные пакеты с цветовыми палитрами: - **{RColorBrewer}** - **{ggsci}** - ... --- # Названия осей ```r p <- p + geom_point(aes(color = species), size = 3, alpha = 0.8) + * labs(x = "Длина клюва (мм)", y = "Высота клюва (мм)", color = "Вид") p ``` <img src="data:image/png;base64,#figs/ggplot_axis_title-1.png" width="80%" style="display: block; margin: auto;" /> --- # Название графика ```r p <- p + * labs(title = "Пингвиньи клювы", * subtitle = "У трех видов пингвинов очень разные клювики.", * caption = "Данные: palmerpenguins") p ``` <img src="data:image/png;base64,#figs/ggplot_title-1.png" width="80%" style="display: block; margin: auto;" /> --- # Сделаем красиво... ```r p + * theme( * plot.title = element_text(size = 18, hjust = 0.5), * axis.title = element_text(face = "italic"), * axis.title.x = element_text(color = "purple")) ``` <img src="data:image/png;base64,#figs/ggplot_theme-1.png" width="80%" style="display: block; margin: auto;" /> --- # Тема: текстовые элементы *Image credit: Emi Tanaka* <img src="data:image/png;base64,#img/ggplot2/ggplot-theme-text-annotation.png" width="100%" style="display: block; margin: auto;" /> --- # Тема: сетка графика *Image credit: Emi Tanaka* <img src="data:image/png;base64,#img/ggplot2/ggplot-annotated-line-marks.png" width="100%" style="display: block; margin: auto;" /> --- # Тема: зоны графика *Image credit: Emi Tanaka* <img src="data:image/png;base64,#img/ggplot2/ggplot-annotated-rect-marks.png" width="80%" style="display: block; margin: auto;" /> --- # Сохранение в файл ```r my_plot <- ggplot(...) + ... # Если не указать переменную с ggplot графиком, то сохранится последний нарисованный график ggsave("figures/my_plot.png", my_plot) ``` ```r ggsave("figures/my_plot.png", my_plot, dpi = 300, width = 10, height = 10, units = "cm") ``` ```r ggsave("figures/my_plot.pdf", my_plot) ``` ```r pdf("figures/my_plot.pdf") # Открыть файл для записи my_plot # Нарисовать график dev.off() # Закрыть файл ``` --- # Geoms .pull-left[ - `geom_point()` - `geom_line()` - `geom_histogram()` - `geom_boxplot()` - `geom_bar()` и `geom_col()` - `geom_text()` и `geom_label()` - ... ] .pull-right[ - точковая диаграмма / scatter plot - линейная диаграмма - гистограмма - ящик с усами / боксплот - столбчатая диаграмма - текст / подписи - ... ] [Как выбрать тип графика под ваши данные](https://www.data-to-viz.com/) --- # Гистограмма Ширину бина или их количество можно задать с помощью `binwidth = ...` или `bins = ...`. ```r ggplot(penguins, aes(x = flipper_length_mm)) + geom_histogram(color = "#ED6A5A", fill = "#F4F1BB") + theme_minimal() ``` <img src="data:image/png;base64,#figs/geom_hist-1.png" width="80%" style="display: block; margin: auto;" /> --- # Гистограмма ```r ggplot(penguins, aes(x = flipper_length_mm, fill = species)) + geom_histogram(color = "white") + scale_fill_manual(values = c("#ED6A5A", "#F4F1BB", "#9BC1BC")) + theme_minimal() ``` <img src="data:image/png;base64,#figs/geom_hist_fill-1.png" width="80%" style="display: block; margin: auto;" /> --- # График плотности Сглаживание можно регулировать с помощью `bw = ...` и других параметров. ```r ggplot(penguins, aes(x = flipper_length_mm, fill = species)) + geom_density(color = "white", alpha = 0.8, bw = 1.5) + scale_fill_manual(values = c("#ED6A5A", "#F4F1BB", "#9BC1BC")) + theme_minimal() ``` <img src="data:image/png;base64,#figs/geom_density-1.png" width="80%" style="display: block; margin: auto;" /> --- # Боксплот ```r ggplot(drop_na(penguins, sex), aes(x = species, y = body_mass_g, fill = sex)) + geom_boxplot(color = "#F4F1BB", width = 0.8) + scale_fill_manual(values = c("#ED6A5A", "#9BC1BC")) + theme_minimal() ``` <img src="data:image/png;base64,#figs/geom_boxplot-1.png" width="80%" style="display: block; margin: auto;" /> --- # Столбчатая диаграмма 🏆 .pull-left[ По умолчанию `position = "stack"` ```r ggplot(penguins, aes(x = species, fill = sex)) + geom_bar(color = "#F4F1BB", width = 0.8) + scale_fill_manual(values = c("#ED6A5A", "#9BC1BC")) + theme_minimal() ``` <img src="data:image/png;base64,#figs/geom_barplot_stack-1.png" width="100%" style="display: block; margin: auto;" /> ] .pull-right[ Можно поменять на `position = "dodge"` ```r ggplot(penguins, aes(x = species, fill = sex)) + geom_bar( color = "#F4F1BB", width = 0.8, * position = "dodge") + scale_fill_manual(values = c("#ED6A5A", "#9BC1BC")) + theme_minimal() ``` <img src="data:image/png;base64,#figs/geom_barplot_dodge-1.png" width="100%" style="display: block; margin: auto;" /> ] --- # Столбчатая диаграмма 🏅 Если уже есть столбец с числами, которые хотим изобразить, то нужно использовать `geom_bar(stat = "identity")` или `geom_col()`. ```r penguins %>% count(species, year) %>% ggplot(aes(x = species, y = n, fill = as_factor(year))) + geom_col(position = "dodge") + scale_fill_manual(values = c("#ED6A5A", "#F4F1BB", "#9BC1BC")) + theme_minimal() ``` <img src="data:image/png;base64,#figs/geom_col-1.png" width="70%" style="display: block; margin: auto;" /> --- # Что почитать и посмотреть - [ggplot2 cheatsheet](https://github.com/rstudio/cheatsheets/blob/master/data-visualization-2.1.pdf) - [ggplot2 website](https://ggplot2.tidyverse.org/reference/index.html) - ['A ggplot2 Tutorial for Beautiful Plotting in R' by Cédric Scherer](https://www.cedricscherer.com/2019/08/05/a-ggplot2-tutorial-for-beautiful-plotting-in-r/) - [The R Graph Gallery](https://www.r-graph-gallery.com/) - [Как выбрать график под ваши данные](https://www.data-to-viz.com/) - [Data Visualization Chapter in R4DS](https://r4ds.had.co.nz/data-visualisation.html) - [ggplot2: elegant graphics for data analysis](https://ggplot2-book.org/) --- # Факторы - Используются для работы с категориальными переменными - Уровни фактора - ограниченное число известных значений категориальной переменной - Для работы с факторами есть пакет `forcats` в составе `tidyverse` ```r library(forcats) # или library(tidyverse) ``` <img src="data:image/png;base64,#img/forcats/forcats.png" width="30%" style="display: block; margin: auto;" /> --- ## Дни недели ```r weekdays <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday") weekdays ``` ``` [1] "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" [7] "Sunday" ``` ```r as.factor(weekdays) # уровни по алфавиту ``` ``` [1] Monday Tuesday Wednesday Thursday Friday Saturday Sunday Levels: Friday Monday Saturday Sunday Thursday Tuesday Wednesday ``` ```r # forcats сохраняет порядок уровней, который был в векторе weekdays_as_fct <- as_factor(weekdays) weekdays_as_fct ``` ``` [1] Monday Tuesday Wednesday Thursday Friday Saturday Sunday Levels: Monday Tuesday Wednesday Thursday Friday Saturday Sunday ``` --- .pull-left[ ```r typeof(weekdays) ``` ``` [1] "character" ``` ```r class(weekdays) ``` ``` [1] "character" ``` ```r as.integer(weekdays) ``` ``` [1] NA NA NA NA NA NA NA ``` ```r sort(weekdays[c(5:7,1:4)]) ``` ``` [1] "Friday" "Monday" "Saturday" "Sunday" "Thursday" "Tuesday" [7] "Wednesday" ``` ] .pull-right[ ```r typeof(weekdays_as_fct) ``` ``` [1] "integer" ``` ```r class(weekdays_as_fct) ``` ``` [1] "factor" ``` ```r as.integer(weekdays_as_fct) ``` ``` [1] 1 2 3 4 5 6 7 ``` ```r sort(weekdays_as_fct[c(5:7,1:4)]) ``` ``` [1] Monday Tuesday Wednesday Thursday Friday Saturday Sunday Levels: Monday Tuesday Wednesday Thursday Friday Saturday Sunday ``` ] --- # Уровни ```r levels(weekdays) ``` ``` NULL ``` ```r levels(weekdays_as_fct) ``` ``` [1] "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" [7] "Sunday" ``` ```r weekdays_as_fct <- weekdays_as_fct[1:3] weekdays_as_fct ``` ``` [1] Monday Tuesday Wednesday Levels: Monday Tuesday Wednesday Thursday Friday Saturday Sunday ``` --- # Создание вектора факторов ```r seasons_with_rep <- c("winter", "winter", "fall", "summer", "sommer", "fall", "fall") seasons_levels <- c("winter", "spring", "summer", "fall") seasons <- factor(seasons_with_rep, levels = seasons_levels) seasons ``` ``` [1] winter winter fall summer <NA> fall fall Levels: winter spring summer fall ``` --- ## fct_count Подсчитать количество факторов каждого уровня. ```r seasons ``` ``` [1] winter winter fall summer <NA> fall fall Levels: winter spring summer fall ``` ```r fct_count(seasons) ``` ``` # A tibble: 5 x 2 f n <fct> <int> 1 winter 2 2 spring 0 3 summer 1 4 fall 3 5 <NA> 1 ``` --- ## fct_drop Удалить неиспользуемые уровни фактора: `spring`. ```r seasons ``` ``` [1] winter winter fall summer <NA> fall fall Levels: winter spring summer fall ``` ```r fct_drop(seasons) ``` ``` [1] winter winter fall summer <NA> fall fall Levels: winter summer fall ``` --- ## fct_explicit_na Приписать отсутствующим уровням (`NA`) явное название. ```r seasons ``` ``` [1] winter winter fall summer <NA> fall fall Levels: winter spring summer fall ``` ```r fct_explicit_na(seasons) # na_level задает название нового уровня ``` ``` [1] winter winter fall summer (Missing) fall fall Levels: winter spring summer fall (Missing) ``` --- ## fct_inorder Упорядочить уровни фактора в порядке встречаемости в векторе. ```r fct_drop(seasons) %>% fct_inorder() # не должно быть неиспользуемых уровней ``` ``` [1] winter winter fall summer <NA> fall fall Levels: winter fall summer ``` -- ## fct_infreq Упорядочить уровни фактора по частоте встречаемости. ```r fct_infreq(seasons) ``` ``` [1] winter winter fall summer <NA> fall fall Levels: fall winter summer spring ``` --- ## fct_rev Изменить порядок уровней на обратный. ```r levels(seasons) ``` ``` [1] "winter" "spring" "summer" "fall" ``` ```r fct_rev(seasons) %>% levels() ``` ``` [1] "fall" "summer" "spring" "winter" ``` -- ## fct_shuffle Перемешать уровни. ```r fct_shuffle(seasons) %>% levels() ``` ``` [1] "summer" "fall" "winter" "spring" ``` --- ## fct_reorder ```r head(iris) ``` ``` Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5.0 3.6 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa ``` ```r iris$Species %>% as_factor() %>% levels ``` ``` [1] "setosa" "versicolor" "virginica" ``` --- ## fct_reorder ```r iris %>% group_by(Species) %>% summarise(min = mean(Sepal.Width)) ``` ``` # A tibble: 3 x 2 Species min <fct> <dbl> 1 setosa 3.43 2 versicolor 2.77 3 virginica 2.97 ``` ```r iris$Species %>% as_factor() %>% fct_reorder(iris$Sepal.Width, min) %>% levels() ``` ``` [1] "versicolor" "virginica" "setosa" ``` См. еще `fct_reorder2`
--- ## fct_lump ```r homeworld_fct <- starwars$homeworld %>% as_factor() %>% fct_explicit_na("Unknown") levels(homeworld_fct) %>% length() ``` ``` [1] 49 ``` ```r fct_count(homeworld_fct, sort = TRUE) %>% head(5) ``` ``` # A tibble: 5 x 2 f n <fct> <int> 1 Naboo 11 2 Tatooine 10 3 Unknown 10 4 Alderaan 3 5 Kamino 3 ``` --- ## fct_lump Семейство функций, которое "схлопывает" часть уровней по условию и создает уровень "Other" (`other_level`). ```r homeworld_fct %>% fct_lump_n(3) %>% table() ``` ``` . Tatooine Naboo Unknown Other 10 11 10 56 ``` --
- `fct_lump_prop` - оставляет уровни, встречающиеся не чаще указанной частоты - `fct_lump_min` - оставляет уровни, встречающиеся не реже указанного числа раз - `fct_lump_lowfreq` - максимально наполняет группу Other так, чтобы она все равно оставалась самой малопредставленной --- # forcats - что почитать - [forcats cheatsheet](https://github.com/rstudio/cheatsheets/blob/master/factors.pdf) - Список всех функций пакета `forcats`: `help(package = "forcats")` - [Factors Chapter in R4DS](https://r4ds.had.co.nz/data-visualisation.html)