Figure 1:

library(ggplot2) #loading ggplot package
library(tidyverse) #loading tidyverse package
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.1     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ lubridate 1.9.5     ✔ tibble    3.3.1
## ✔ purrr     1.2.2     ✔ tidyr     1.3.2
## ── 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
install.packages("factoextra") #install factoextra package for pca
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.5'
## (as 'lib' is unspecified)
library(factoextra) #loading factoextra package
## Welcome to factoextra!
## Want to learn more? See two factoextra-related books at https://www.datanovia.com/en/product/practical-guide-to-principal-component-methods-in-r/
library(ggrepel) #loading in ggrepel, to fix overlapping text in pca graph
library(patchwork) #loading in patchwork, to put the m/f pca plots side-by-side and enhance male barplot figure
Bluebird_Data <- read_csv("Bluebird_Data.csv") #loading in eastern bluebird dataset
## Rows: 250 Columns: 20
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (5): BIRDSEX, NS_GP2, DATE, TIME, NOISE
## dbl (15): BIRDID, NEST, CLUTCH, PEEK, POKE, GAPE, ONBOX, ATHOLE, IN, OUT, PB...
## 
## ℹ 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.
male <- Bluebird_Data %>% #split up data 
  filter(BIRDSEX == "M") #filter by males only
  
fem <- Bluebird_Data %>% #split up data
  filter(BIRDSEX == "F") #filter by females only

f_behaviors <- c("POKE", "PEEK", "GAPE", "ONBOX") #define female behavior categories
m_behaviors <- c("ATHOLE", "OUT", "IN", "ONBOX") #define male behavior categories


m_data <- male %>% #refine data
  select(all_of(m_behaviors)) %>% #incl all above behavior variables
  na.omit() #omit N/A data

m_pca <- prcomp(m_data, scale. = TRUE) #setting up male only PCA
m_df <- as.data.frame(m_pca$x) #final dataframe for ggplotting
m_loadings <- as.data.frame(m_pca$rotation) #define 'loadings' for male data
m_loadings$var <- rownames(m_loadings) #define 'var' to use place of rownames

m_plot <- ggplot(data = m_df, aes(x = PC1, y = PC2)) + #specify dataset & x/y axes
  geom_point(color= "royalblue3", size=4, shape=18, alpha= 0.7) + #point color, size, shape
  geom_segment(data = m_loadings, #create segments with loadings
               aes(x=0, y=0, xend = PC1, yend = PC2), #choose segment x/y end
               inherit.aes = FALSE,
               color = "magenta2") + #color arrows on loading plot
  geom_text_repel(data = m_loadings, #fixing overlapping text on loading plot
                  aes(PC1, PC2, label = var, #set x/y axes and specify segments lead to rownames (containing target behaviors)
                  fontface = "bold"))+ #make labels bold
  theme_gray() + #alter theme to incl light gray background
  ggtitle("Male Bluebird PCA") + #title
   coord_cartesian(xlim= c(-1,3), ylim= c(-2, 3)) #set x/y limits to 'zoom in' on the data

f_data <- fem %>% #refine data
  select(all_of(f_behaviors)) %>% #incl all above behavior variables
  na.omit() #omit N/A data

f_pca <- prcomp(f_data, scale. = TRUE) #setting up female only PCA
f_df <- as.data.frame(f_pca$x) #final dataframe for ggplotting
f_loadings <- as.data.frame(f_pca$rotation) #define 'loadings' for females
f_loadings$var <- rownames(f_loadings) #define 'var' to use place of rownames


f_plot <- ggplot(data = f_df, aes(x = PC1, y = PC2)) + #specify dataset & x/y axes
  geom_point(color= "magenta3", size=4, shape=18, alpha = 0.7) + #point color, size, shape
  geom_segment(data = f_loadings, #create segments with loadings
               aes(x=0, y=0, xend = PC1, yend = PC2), #choose segment x/y end
               inherit.aes = FALSE,
               color = "royalblue") + #color arrows on loading plot
  geom_text_repel(data = f_loadings, #fixing overlapping text on loading plot
                  aes(PC1, PC2, label = var, #set x/y axes and specify segments lead to rownames (containing target behaviors)
                  fontface = "bold"))+ #make labels bold
  theme_gray() + #alter theme to incl light gray background
  ggtitle("Female Bluebird PCA") + #title
  coord_cartesian(xlim= c(-1,3), ylim= c(-2, 3)) #set x/y limits to 'zoom in' on the data

m_plot + f_plot #display the two plots side-by-side

Original Figure:

knitr::include_graphics("figure4.png") #embed original figure PNG & adjust the size (above)

Figure 2:

library(cowplot) #loading in cowplot package for adding small zoom-in window of male data
## 
## Attaching package: 'cowplot'
## The following object is masked from 'package:patchwork':
## 
##     align_plots
## The following object is masked from 'package:lubridate':
## 
##     stamp
bluebirds <- Bluebird_Data %>% #alter & rename the data
  group_by(BIRDSEX, NS_GP2) %>% #group data by sex & noise category
  summarise(across(c(PEEK, POKE, GAPE, ONBOX), #create summary data across target behaviors
                   list(
                   Mean = ~mean(.x, na.rm = TRUE), #define "Mean"
                   SE = ~sd(.x, na.rm = TRUE) / sqrt(sum(!is.na(.x))) #define "SE"
                   )),
            .groups = "drop") #tidying up

long_birds <- bluebirds %>% #alter & rename the data again to pivot it longer
  pivot_longer(cols= -c(BIRDSEX, NS_GP2), #pivot the data
               names_to = c("Behavior", ".value"), #name new column
               names_sep = "_") #new column for mean data

fig.2 <- ggplot(long_birds, aes(x= NS_GP2, y= Mean, fill= Behavior))+ #graph by noise category, mean, & fill by behavior
  geom_bar(position= position_dodge(width= 1), stat= "identity") + #create grouped barplot & specify width
  geom_errorbar(aes(ymin= Mean-SE, ymax= Mean + SE), #create SE bars, specifying the max/min error bar values
                position = position_dodge(width=1), #error bar position & width
                width = 0.5)+ #error bar top/bottom line width
  facet_wrap(~BIRDSEX, scales='free') + #facet wrap to have both male & female graphs side-by-side
  labs(
    x = "Noise Categories", #x axis title
    y = "Mean Behavior per Hour", #y axis title
    title = "Average Observed Behavior by Noise Category") + #figure title
  theme_bw() #selected theme

fig.2.zoom <- long_birds %>% #creating zoomed-in version of males only
  dplyr::filter(BIRDSEX == "M",
                NS_GP2 %in% c("Q", "QPI", "QPA")) %>% #only include male data
  ggplot(aes(x= NS_GP2, y= Mean, fill= Behavior)) + #ploting noise category, mean, and fill by behavior type
  geom_bar(position= position_dodge(width= 1), stat= "identity") + #create grouped barplot & specify width
  geom_errorbar(aes(ymin= Mean-SE, ymax= Mean + SE), #create SE bars, specifying the max/min error bar values
                position = position_dodge(width=1), #error bar position & width
                width = 0.5)+ #error bar top/bottom line width
  coord_cartesian(ylim = c(0, 0.3)) + #specify zoom-in max/min
  theme_bw() + #select theme
  theme(legend.position = "none", #no legend
        axis.title.x = element_blank(), #no x axis title
        axis.title.y = element_blank()) #no y axis title

ggdraw() + #combine the original figure and the zoomed in figure
  draw_plot(fig.2) + 
  draw_plot(fig.2.zoom, x= 0.54, y= 0.57, #input zoomed figure, x/y indicate location on graph (as close as possible w/o touching the edges)
            width = 0.3, height = 0.3) #specify the zoomed view size

Original Figure:

knitr::include_graphics("figure3.png") #embed original figure PNG & adjust the size (above)