Введение

Эта небольшая работа анализирует данные из проектов City Nature Challenge 2022 для Санкт-Петербурга и Екатеринбурга на платформе iNaturalist.Данные проекты взяты для нынешней работы в рамках изучения влияние урбанизации (измеряемой количеством населения) на количество наблюдений, разнообразие видов (количество уникальных видов) и другие параметры. Данные взяты из отчетов на iNaturalist на конец периода наблюдений (2 мая 2022 г.). Население городов за 2022 год: Санкт-Петербург - 5,600,044; Екатеринбург - 1,589,000

Цель: Узнать, как урбанизация будет влиять на видовое разнообразие популяций в городах, схожих по площади,но крайне различны в плотности застройки и численности населения.

Карты наблюдений City Nature Challenge 2022

Перейдите по ссылкам, затем выберите вкладку «Observations» → «Map» для просмотра интерактивной карты.

Статистика по типу наблюдений

library(ggplot2)
library(dplyr)
## Warning: пакет 'dplyr' был собран под R версии 4.5.2
## 
## Присоединяю пакет: 'dplyr'
## Следующие объекты скрыты от 'package:stats':
## 
##     filter, lag
## Следующие объекты скрыты от 'package:base':
## 
##     intersect, setdiff, setequal, union
library(patchwork)   # для объединения графиков
## Warning: пакет 'patchwork' был собран под R версии 4.5.2
# Данные
data <- data.frame(
  City = c(rep("Санкт-Петербург", 2), rep("Екатеринбург", 2)),
  Category = rep(c("Research Grade", "Needs ID"), 2),
  Count = c(2313, 246, 3981, 752)
) %>%
  group_by(City) %>%
  mutate(Percent = Count / sum(Count) * 100,
         Label = paste0(Category, "\n", Count, " (", round(Percent, 1), "%)"))

# Функция для создания кольцевой диаграммы
make_donut <- function(city_data, city_name) {
  ggplot(city_data, aes(x = 2, y = Count, fill = Category)) +
    geom_col(width = 0.9, color = "white") +
    coord_polar("y", start = 0) +
    xlim(0.5, 2.5) +
    geom_text(aes(y = Count/2 + c(0, cumsum(Count)[-length(Count)]), 
                  label = Label),
              size = 4, color = "white", fontface = "bold") +
    scale_fill_manual(values = c("Research Grade" = "#2ecc71", 
                                "Needs ID" = "#e74c3c")) +
    labs(title = city_name) +
    theme_void() +
    theme(legend.position = "bottom",
          plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
          legend.title = element_blank())
}

# Создаём графики
p1 <- make_donut(filter(data, City == "Санкт-Петербург"), "Санкт-Петербург")
p2 <- make_donut(filter(data, City == "Екатеринбург"), "Екатеринбург")

# Объединяем графики рядом
p1 + p2 + 
  plot_annotation(
    title = "Сравнение Research Grade и Needs ID наблюдений\nCity Nature Challenge 2022",
    theme = theme(plot.title = element_text(size = 16, hjust = 0.5))
  )

Статистика по видам живых существ

Распределение количества видов по основным группам (CNC 2022)

library(ggplot2)
library(dplyr)
library(patchwork)

# Данные
data <- data.frame(
  City = c(rep("Санкт-Петербург", 14), rep("Екатеринбург", 14)),
  Group = rep(c("Неизвестно", "Простейшие", "Грибы", "Растения", "Хромисты",
                "Моллюски", "Насекомые", "Паукообразные", "Лучепёрые рыбы",
                "Земноводные", "Пресмыкающиеся", "Птицы", "Млекопитающие", 
                "Другие животные"), 2),
  Species = c(4,0,25,184,0,6,34,8,2,2,0,107,9,1,     # СПб
              5,0,57,337,0,9,67,8,0,4,1,93,10,10)    # Екб
)

# Функция построения одного пончика
make_simple_donut <- function(city_name) {
  df_city <- data %>% filter(City == city_name)
  
  df_city <- df_city %>%
    filter(Species > 0) %>%              # убираем нулевые для чистоты
    mutate(
      pos = cumsum(Species) - Species/2,
      label = ifelse(Species >= 10, paste0(Group, "\n", Species), Species)
    )
  
  ggplot(df_city, aes(x = "", y = Species, fill = Group)) +
    geom_col(width = 0.7, color = "white") +
    coord_polar("y", start = 0) +
    scale_x_discrete(limits = c("", "inner")) +   # ключевой трюк для избежания ошибки
    geom_text(aes(y = pos, label = label),
              color = "white", size = 3.3, fontface = "bold") +
    labs(title = paste(city_name, "\nвсего видов:", sum(df_city$Species))) +
    theme_void() +
    theme(
      legend.position = "none",
      plot.title = element_text(hjust = 0.5, size = 13, face = "bold")
    )
}

# Цвета (можно оставить или убрать scale_fill_manual, если не нужны)
my_colors <- scales::hue_pal()(length(unique(data$Group)))

# Графики
p_spb <- make_simple_donut("Санкт-Петербург") + 
  scale_fill_manual(values = my_colors)

p_ekb <- make_simple_donut("Екатеринбург") + 
  scale_fill_manual(values = my_colors)

# Объединение
p_spb + p_ekb +
  plot_annotation(
    title = "Количество видов по основным группам • City Nature Challenge 2022",
    theme = theme(plot.title = element_text(size = 15, hjust = 0.5))
  ) +
  plot_layout(guides = "collect") & 
  theme(legend.position = "bottom",
        legend.title = element_blank())

Влияние населения на количество наблюдений

ggplot(cities, aes(x = Population, y = Observations)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Зависимость количества наблюдений от населения",
       x = "Население", y = "Наблюдения") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Влияние населения на разнообразие видов

ggplot(cities, aes(x = Population, y = Species)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Зависимость количества видов от населения",
       x = "Население", y = "Виды") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Нормализованные метрики

Чтобы учесть влияние количества участников, рассчитаем виды на участника и наблюдения на участника.

cities$Species_per_Participant <- cities$Species / cities$Participants
cities$Obs_per_Participant <- cities$Observations / cities$Participants

knitr::kable(cities[, c("City", "Species_per_Participant", "Obs_per_Participant")], caption = "Нормализованные метрики")
Нормализованные метрики
City Species_per_Participant Obs_per_Participant
Санкт-Петербург 3.472727 23.26364
Екатеринбург 11.784314 92.80392

Влияние населения на виды на участника

ggplot(cities, aes(x = Population, y = Species_per_Participant)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Зависимость видов на участника от населения",
       x = "Население", y = "Виды на участника") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Выводы

На основе данных наблюдается отрицательная корреляция между населением и количеством наблюдений/видов. Нормализованные метрики показывают, что в Екатеринбурге (менее урбанизированном) виды на участника выше (11.784314 vs 3.472727), что может указывать на такие факторы как география, климат и тд. В конце можно предположить,что более плотная урбанизированная местность, численность людей и тд. не являются благоприятным условием для биорознаообразия на урбанизированых территориях.