Для анализа данных о пингвинах нам потребуются следующие пакеты:
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.2.0 ✔ readr 2.2.0
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.2 ✔ tibble 3.3.1
## ✔ lubridate 1.9.5 ✔ tidyr 1.3.2
## ✔ purrr 1.2.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(palmerpenguins)
##
## Присоединяю пакет: 'palmerpenguins'
##
## Следующие объекты скрыты от 'package:datasets':
##
## penguins, penguins_raw
library(ggthemes)
library(viridis)
## Загрузка требуемого пакета: viridisLite
library(ggplot2)
Создадим чистый набор данных без пропущенных значений и добавим новые переменные для более глубокого анализа:
Соотношение длины и глубины клюва (bill_ratio); Индекс “плотности” тела (body_condition); Категоризация по размеру (size_category); Русскоязычные названия для видов, полов и островов
penguins_clean <- penguins %>%
drop_na() %>%
mutate(
bill_ratio = bill_length_mm / bill_depth_mm, #соотношение длины и глубины клюва
body_condition = body_mass_g / flipper_length_mm, #"плотность" тела
island_year = paste(island, year, sep = "_"),
size_category = case_when(
body_mass_g < 3500 ~ "Мелкие",
body_mass_g < 4500 ~ "Средние",
TRUE ~ "Крупные"
),
species_rus = case_when(
species == "Adelie" ~ "Адели",
species == "Chinstrap" ~ "Чинстрап",
species == "Gentoo" ~ "Генту"
),
sex_rus = ifelse(sex == "male", "Самец", "Самка"),
island_rus = case_when(
island == "Biscoe" ~ "Биско",
island == "Dream" ~ "Дрим",
island == "Torgersen" ~ "Торгерсен"
)
)
Создадим комплексный график, показывающий взаимосвязь между длиной и глубиной клюва у разных видов пингвинов.
anatomy_plot <- penguins_clean %>%
ggplot(aes(
x = bill_length_mm,
y = bill_depth_mm,
color = species_rus
)) +
geom_point(
aes(shape = sex_rus),
size = 3,
alpha = 0.7
) +
stat_ellipse(
aes(group = species),
level = 0.95,
linetype = "dashed",
linewidth = 0.8,
alpha = 0.5,
show.legend = FALSE
) +
geom_smooth(
aes(group = interaction(species, sex)),
method = "lm",
se = FALSE,
linetype = "dotted",
linewidth = 0.5,
alpha = 0.4,
show.legend = FALSE
) +
facet_wrap(~ species_rus, scales = "free") +
scale_color_viridis_d(
option = "plasma",
begin = 0.2,
end = 0.8,
name = "Вид"
) +
scale_shape_manual(values = c(16, 17), name = "Пол") +
labs(
title = "Анатомия клюва: Различия между видами и полами",
subtitle = "Соотношение длины и глубины клюва с доверительными эллипсами (95%)",
x = "Длина клюва (мм)",
y = "Глубина клюва (мм)",
caption = "Пунктирные линии - линейные тренды для каждого пола"
) +
theme_minimal(base_size = 14) +
theme(
legend.position = "bottom",
legend.box = "horizontal",
plot.title = element_text(face = "bold", size = 18, hjust = 0.5),
plot.subtitle = element_text(color = "gray40", size = 12, hjust = 0.5),
strip.background = element_rect(fill = "gray90", color = NA),
strip.text = element_text(face = "bold", size = 12),
panel.grid.minor = element_blank(),
panel.border = element_rect(fill = NA, color = "gray70")
) +
guides(
color = guide_legend(override.aes = list(size = 5)),
shape = guide_legend(override.aes = list(size = 5))
)
Выведем созданный график на экран и сохраним его в файл с высоким разрешением:
anatomy_plot
## `geom_smooth()` using formula = 'y ~ x'
ggsave("penguins_anatomy.png", anatomy_plot, width = 14, height = 8, dpi = 300)
## `geom_smooth()` using formula = 'y ~ x'
На созданном графике можно наблюдать четкие различия в форме клюва между тремя видами пингвинов. Вид Генту отличается наиболее длинным и менее глубоким клювом, в то время как у пингвинов Адели и Чинстрап клювы короче, но глубже. Также заметны половые различия внутри каждого вида: самцы (треугольники) обычно имеют немного большие размеры клюва по сравнению с самками (круги). Доверительные эллипсы подтверждают, что виды хорошо разделяются по этим признакам.