Для анализа данных о пингвинах нам потребуются следующие пакеты:

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'

На созданном графике можно наблюдать четкие различия в форме клюва между тремя видами пингвинов. Вид Генту отличается наиболее длинным и менее глубоким клювом, в то время как у пингвинов Адели и Чинстрап клювы короче, но глубже. Также заметны половые различия внутри каждого вида: самцы (треугольники) обычно имеют немного большие размеры клюва по сравнению с самками (круги). Доверительные эллипсы подтверждают, что виды хорошо разделяются по этим признакам.