2025-04-14

Introduction

Khanbumbat Airport is a privately operated local airport owned by the Oyu Tolgoi mining company. It serves as a key transportation hub for approximately 20,000 mine workers who commute to the site. The mine is located in the southern region of Mongolia.

This airport started bird research monitoring since 2019th.All of international and local airport need to managing bird control in airport area. Bird strikes cost civil aviation organizations around the world $1.2 billion annually.The first recorded bird strike was experienced by the Wright Flyer III on 7 September 1905. A lot of studies specified that 96% of strikes occur during take-off, climb, approach and landing. Therefore, It is important to protect from bird strike with airplane.

This report’s main objective is that the defining the annual dynamic of bird species in this airport.

Research questions

  1. Is there an increasing or decreasing trend in bird abundance and species richness over the past five years of monitoring?

  2. How do the monthly dynamics of bird species abundance and richness vary throughout the year?

  3. How do temperature and precipitation influence bird abundance and species richness?

## Study area

Khanbumbat Airport, Umnugobi Province, Mongolia

library(leaflet)
## Warning: package 'leaflet' was built under R version 4.4.3
leaflet() %>%  
  addTiles() %>%  
   addMarkers(lng = 106.84638, lat = 43.13472, popup = "Khanbumbat Airport")

Methods

Data collection

Point count method

  1. 9 plots
  2. Four seasons
  3. 06:00 am - 00:00 am
  4. 5-6 times in the day
  5. ArcGIS Survey123 application. This application works online and offline mode, records bird species, time, abundance, flight height, direction and weather.

Data background

Importing Data and package

library(readr)
## Warning: package 'readr' was built under R version 4.4.2
birdy<- read_csv("C:/Users/aotgo/OneDrive/Documents/ESF Classes/R class 2025/Project_Bird.data/R class_Analyze_Year_diversity 2025.csv")
## Rows: 5313 Columns: 12
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (9): Scientific name, Order Latin name, Date, Time, Months, Season, Orde...
## dbl (3): Number, Log10, Years
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Data summary

summary(birdy)
##  Scientific name    Order Latin name       Date               Number       
##  Length:5313        Length:5313        Length:5313        Min.   :   1.00  
##  Class :character   Class :character   Class :character   1st Qu.:   1.00  
##  Mode  :character   Mode  :character   Mode  :character   Median :   2.00  
##                                                           Mean   :  16.05  
##                                                           3rd Qu.:   8.00  
##                                                           Max.   :2748.00  
##      Log10            Time              Months             Season         
##  Min.   :0.0000   Length:5313        Length:5313        Length:5313       
##  1st Qu.:0.0000   Class :character   Class :character   Class :character  
##  Median :0.3010   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :0.5849                                                           
##  3rd Qu.:0.9031                                                           
##  Max.   :3.4390                                                           
##   Order code            Years      Living type        Threat gategories 
##  Length:5313        Min.   :2019   Length:5313        Length:5313       
##  Class :character   1st Qu.:2020   Class :character   Class :character  
##  Mode  :character   Median :2020   Mode  :character   Mode  :character  
##                     Mean   :2021                                        
##                     3rd Qu.:2022                                        
##                     Max.   :2023

Study result (The yearly dynamic of bird abundance)

library(ggplot2)
ggplot(data = birdy,aes(x = Years, y = birdy$Log10))+
  geom_bar(aes(fill = `Living type`),
           stat = 'identity') + facet_wrap(~'Living type',
          scales = 'fixed')+
     labs(title = "Bird Abundance at Khanbumbat Airport")+
     geom_line()+ylab("Abundance") 

Plot Output

## Warning: package 'ggplot2' was built under R version 4.4.2

Anova (abundance)

anova_abundance<-  aov(birdy$Log10 ~ Years, data = birdy)
summary(anova_abundance)
library(ggplot2)
boxplot(birdy$Log10 ~ Years, 
      data = birdy,
       col = "lightblue",
        main = "ANOVA Boxplot: Bird abundance by years",
      xlab = "Years",
       ylab = "Abundance")

Plot output (Anova)

##               Df Sum Sq Mean Sq F value Pr(>F)    
## Years          1     98   97.98   284.2 <2e-16 ***
## Residuals   5311   1831    0.34                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Bird strike (Khanbumbat Airport)

Monthly dynamic in bird Abundance

anova_month<-  aov(birdy$Log10 ~ birdy$Months, data = birdy)
summary(anova_month)
birdy$Months <- factor(birdy$Months, levels = month.abb)
library(ggplot2)
boxplot(Log10 ~ Months, data = birdy,
        main = "Abundance by month",
        xlab = "Months", ylab = "Abundance (Log10)",
         col = "orange")

Plot output (abundance by month)

##                Df Sum Sq Mean Sq F value Pr(>F)    
## birdy$Months   11  547.7   49.79   191.1 <2e-16 ***
## Residuals    5301 1381.2    0.26                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

The yearly dynamic of species richness

Reshaping

library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.2
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
species_richness_by_year_livingtype <- birdy %>%
group_by(Years, `Living type`) %>%
summarise(Number_of_Species = n_distinct(`Scientific name`),.groups = "drop")

Species richness

library(ggplot2)
ggplot(species_richness_by_year_livingtype,+
       aes(x=Years,y=Number_of_Species,group = `Living type`))+
   geom_line(size=1)+
  geom_point(size=1.5)+
  labs(title = "Species richness by Year and Living type",
       x="Years",
       y="Species Richness")+
  theme_minimal()

Plot output (Species richness)

Anova (Species richness)

anova_sprichness<-  aov(species_richness_by_year_livingtype$Number_of_Species ~ Years, data = species_richness_by_year_livingtype)
summary(anova_sprichness)
library(ggplot2)
boxplot(Number_of_Species ~ Years, 
      data = species_richness_by_year_livingtype,
       col = "red",
        main = "ANOVA Boxplot: Species richness by years",
      xlab = "Years",
       ylab = "Species richness")

Plot output (species richness)

##             Df Sum Sq Mean Sq F value Pr(>F)
## Years        1      3    2.98    0.01  0.921
## Residuals   21   6255  297.85

Data import

library(readr)
R_class_monthly_2025 <- readr::read_csv("C:/Users/aotgo/OneDrive/Documents/ESF Classes/R class 2025/Project_Bird.data/R_class_monthly_2025.csv")
## Rows: 5313 Columns: 12
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (9): Scientific name, Order Latin name, Date, Time, Months, Season, Orde...
## dbl (3): Number, Log10, Years
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Reshaping (Species richness by months)

library(dplyr)
sprich_by_month<-R_class_monthly_2025 %>%
  group_by(Years,Months)%>%
  summarise(Number_of_Species=n_distinct(`Scientific name`),.groups = "drop")

Monthly dynamic in species richness

R_class_monthly_2025 <- 
  read_csv("ESF Classes/R class 2025/Project_Bird.data/R_class_monthly_2025.csv")
Reshaping
sprich_by_month<- R_class_monthly_2025 %>%
group_by(Years, Months) %>%
summarise(Number_of_Species = n_distinct(`Scientific name`),
          .groups = "drop")
> sprich_by_month
anova_month_sprich<-  aov(Number_of_Species ~ Months,
                          data = sprich_by_month)
summary(anova_month_sprich)
sprich_by_month$Months <- factor(sprich_by_month$Months, 
                                 levels = month.abb)
library(ggplot2)
boxplot(Number_of_Species ~ Months, data = sprich_by_month,
        main = "Species richness by month",
        xlab = "Months", ylab = "Species richness",
        col = "orange")

Plot out

##             Df Sum Sq Mean Sq F value   Pr(>F)    
## Months      11   3837   348.8   7.692 3.37e-07 ***
## Residuals   44   1995    45.3                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Reshaping for Correlation (sprichness)

spr_monthly <- R_class_monthly_2025 %>%
group_by(Years, Months) %>%
summarise(Species_richness = n_distinct(`Scientific name`), .groups = "drop")
spr_monthly
## # A tibble: 56 × 3
##    Years Months Species_richness
##    <dbl> <chr>             <int>
##  1  2019 Apr                  23
##  2  2019 Aug                  32
##  3  2019 Dec                   6
##  4  2019 Jul                  25
##  5  2019 Jun                  24
##  6  2019 May                  41
##  7  2019 Nov                  11
##  8  2019 Oct                  20
##  9  2019 Sep                  35
## 10  2020 Apr                  25
## # ℹ 46 more rows

Reshaping for Correlation (abundance)

R_class_monthly_2025$Months <- factor(R_class_monthly_2025$Months, 
  levels = c("Jan", "Feb", "Mar", "Apr", "May", "Jun", 
         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))
abundance_monthly <- R_class_monthly_2025 %>% 
group_by(Years, Months) %>%
summarise(Abundance = sum(Log10), .groups = "drop")
abundance_monthly
## # A tibble: 56 × 3
##    Years Months Abundance
##    <dbl> <fct>      <dbl>
##  1  2019 Apr         34.8
##  2  2019 May         74.4
##  3  2019 Jun         52.4
##  4  2019 Jul         52.4
##  5  2019 Aug         63.5
##  6  2019 Sep         53.7
##  7  2019 Oct         68.2
##  8  2019 Nov         39.9
##  9  2019 Dec         34.8
## 10  2020 Jan         36.3
## # ℹ 46 more rows

Weather Conditions (Average temperature)

library(readr)
R_class_weather_data_2025 <- read_csv("~/ESF Classes/R class 2025/R_class_weather_data_2025.csv")
library(ggplot2)
library(dplyr)
weather_df<-data.frame(Year=c(R_class_weather_data_2025$Year),Month=c(R_class_weather_data_2025$Month),Temp=c(R_class_weather_data_2025$`Average of Temp_avg`))

weather_df$Month <- factor(weather_df$Month,
                           levels = month.abb)
ggplot(weather_df, aes(x = Month, y = Temp, group = Year, color = as.factor(Year))) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  labs(title = "Monthly Temperature Trends (2019–2023)",
       x = "Month", y = "Temperature (°C)", color = "Year") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

Plot (Temperature)

Weather Conditions (Average Wind)

library(readr)
R_class_weather_data_2025 <- read_csv("~/ESF Classes/R class 2025/R_class_weather_data_2025.csv")
library(ggplot2)
library(dplyr)
weather_dw<-data.frame(Year=c(R_class_weather_data_2025$Year),Month=c(R_class_weather_data_2025$Month),Wind=c(R_class_weather_data_2025$`Average of WindSpd_Avg`))
weather_dw$Month <- factor(weather_df$Month,
                           levels = month.abb)
ggplot(weather_dw, aes(x = Month, y = Wind, group = Year, color = as.factor(Year))) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  labs(title = "Monthly WindTrends (2019–2023)",
       x = "Month", y = "Wind (m/s)", color = "Year") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

Plot (Wind)

Weather Conditions (Average Precipitation)

library(readr)
R_class_weather_data_2025 <- read_csv("~/ESF Classes/R class 2025/R_class_weather_data_2025.csv")
library(ggplot2)
library(dplyr)
weather_dp<-data.frame(Year=c(R_class_weather_data_2025$Year),Month=c(R_class_weather_data_2025$Month),Precip=c(R_class_weather_data_2025$`Average of Precip_mm_avg`))
weather_dp$Month <- factor(weather_df$Month,
                           levels = month.abb)
ggplot(weather_dp, aes(x = Month, y = Precip, group = Year, color = as.factor(Year))) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  labs(title = "Monthly Precipitation Trends (2019–2023)",
       x = "Month", y = "Precipitation (mm)", color = "Year") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

Plot (Precipitation)

Correlation

library(readr)
R_class_weather_data_2025 <- read_csv("~/ESF Classes/R class 2025/R_class_weather_data_2025.csv")
df <- read_csv("~/ESF Classes/R class 2025/R_class_weather_data_2025.csv")
factors <- df[, c("Average of Temp_avg", "Average of WindSpd_Avg", "Average of Precip_mm_avg")]
params <- df[, c("Abundance (log10)", "Species richness")]
cor_matrix <- cor(factors, params, use = "complete.obs")
round(cor_matrix, 2)
library(reshape2)
cor_melted<- melt(cor_matrix)
library(ggplot2)
ggplot(cor_melted, aes(x = Var2, y = Var1, fill = value))+
  geom_tile(color = "white") +
  geom_text(aes(label = round(value, 2)), color = "black", size = 4) +
  scale_fill_gradient2(low = "orange", mid = "white", high = "darkgreen", midpoint = 0,
                       limit = c(-1, 1), name = "Pearson\nCorrelation") +limit = c(-1, 1), name = "Pearson\nCorrelation") +
  theme_minimal() +
  labs(title = "Correlation: Environmental Factors vs Richness and Abundance",x = "Richness and Abundance", y = "Environmental Factors") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot (Correlation heatmap)

##                          Abundance (log10) Species richness
## Average of Temp_avg                  -0.40             0.72
## Average of WindSpd_Avg               -0.22             0.15
## Average of Precip_mm_avg              0.00             0.45

Conclusion

  1. Species richness shows a strong positive correlation with average temperature (r = 0.72) and a moderate positive correlation with precipitation (r = 0.45), suggesting that warmer and wetter conditions support greater biodiversity.

  2. Abundance is moderately negatively correlated with temperature (r = -0.40) and wind speed (r = -0.22), indicating that higher temperatures and stronger winds may reduce the number of individuals.

  3. Precipitation shows no correlation with abundance (r = 0.00), and wind speed has only a weak positive relationship with species richness (r = 0.15).

Conclusion

  1. Bird abundance is higher in the winter season compared to other seasons, but species richness is lower.Species richness at Khanbumbat Airport is higher from late spring to late summer.

  2. Both high bird abundance and high species richness increase the risk of bird strikes. Therefore, during spring and summer, it is important to use effective and varied bird-scaring devices around airport landing and take-off areas.During the winter, bird-scaring activities should be conducted daily.

  3. In summer, the number of large-bodied bird species increases, while in winter, flocking bird species and overall abundance tend to rise.