SETUP

WORKING DIRECTORY

setwd(“D:/adult shit/Career/Masters/S2026/Capstone/R”)

PACKAGES

if (!requireNamespace(“pacman”, quietly = TRUE)) { install.packages(“pacman”) }

library(pacman) p_load( tidyverse, RColorBrewer, glmmTMB, emmeans, openxlsx, ggpubr, paletteer, ggrepel )

READ IN DATA

olive_data <- read.xlsx( “Olive PTSD Raw Data (for Chandler).xlsx”, sheet = 1, colNames = TRUE )

DATA CLEANING

REMOVE UNNECESSARY COLUMNS

olive_data <- olive_data %>% select(-Configuration.Name, -Date, -Time, -Observer, -DeviceID, -Edited, -Session.Start.Time, -Recorded.Start.Time, -Session.End.Time, -Month, -Hour, -Project.Animals, -Duration, -Habitat.Map, -Grid.Size, -Image.Size, -Notes, -Subject.Type, -Focal.Name, -Group.Count, -Interval.Channel.1.Name, -Question:.Type.of.Data.Collection_133, -Question:.Indoor/Outdoor?_49 )

RENAMING COLUMNS

olive_data <- olive_data %>% rename( Behavior_Channel = Channel.Type, All_Occurrence_Behavior = All.Occurrence.Value, All_Occurrence_Behavior_Modifier_1 = All.Occurrence.Behavior.Modifier.1, Continuous_Channel_1_Name = Continuous.Channel.1.Name, Continuous_Channel_1_Behavior = Continuous.Channel.1.Value, Continuous_Channel_1_Duration_s = Continuous.Channel.1.Duration.(sec), Continuous_Channel_2_Name = Continuous.Channel.2.Name, Continuous_Channel_2_Behavior = Continuous.Channel.2.Value, Continuous_Channel_2_Duration_s = Continuous.Channel.2.Duration.(sec), Frame_Number = Frame.Number, Interval_Scan_Behavior = Interval.Channel.1.Value, Interval_Scan_Modifier = Interval.Channel.1.Behavior.Modifier.1, Human_Presence_Last_30s = Interval.Channel.2.Name, Human_Present_Win_5BL = Interval.Channel.2.Value, Conspecific_Proximity = Interval.Channel.3.Name, BL_Dist = Interval.Channel.3.Value, Video_File_Name = Question:.Video.File.Name_46, Date = Question:.Date_41, Time = Question:.Time_42, Phase = Question:.Phase.of.Data.Collection_44, Temp(F) = Question:.Temperature.(F)_47, Wind_Speed(mph) = Question:.Wind.Speed.(mph)_48, Weather_Condition = Question:.Weather.Condition_45 )

FIXING DATA

olive_data\(Date <- as.Date(olive_data\)Date, origin = “1899-12-30”)

FIXING TIME

olive_data <- olive_data %>% mutate( Time = as.numeric(as.character(Time)), # convert factor/char to numeric Time = format( as.POSIXct(Time * 24 * 60 * 60, origin = “1970-01-01”, tz = “UTC”), “%H:%M” ) )

REMOVING OUT OF VIEW SCANS

olive_data <- olive_data %>% mutate( # Set both Interval_Scan_Behavior and Interval_Scan_Modifier to NA when ‘Out of View’ is recorded Interval_Scan_Behavior = ifelse(Interval_Scan_Behavior == “Out of View”, NA, Interval_Scan_Behavior), Interval_Scan_Modifier = ifelse(Interval_Scan_Behavior == “Out of View”, NA, Interval_Scan_Modifier) )

ADDING HUMAN PRESENCE 1/0

olive_data <- olive_data %>% mutate( Human_Presence = ifelse( is.na(Human_Presence_Last_30s) | Human_Presence_Last_30s != “Humans Present (within the last 30 seconds)”, 0, 1 ), Human_Presence = factor(Human_Presence, levels = c(0, 1), labels = c(“Absent”, “Present”)) )

ADDING WEEK NUMBER COLUMN

start_date <- as.Date(“2024-11-27”)

olive_data <- olive_data %>% mutate( Week_Number = 1 + floor(as.numeric(difftime(Date, start_date, units = “days”)) / 7) )

DESCRIPTIVE STATS

ALL PHASES DESCRIPTIVES

SCAN BEHAVIOR DATA

scan_behaviors <- olive_data %>% filter(Behavior_Channel == “Interval”) %>% mutate( scan_behavior = if_else( !is.na(Interval_Scan_Modifier), paste(Interval_Scan_Behavior, Interval_Scan_Modifier, sep = “_“), Interval_Scan_Behavior ) )

SCAN BEHAVIOR OCCURRENCE RATES

scan_behavior_rates <- scan_behaviors %>% count(scan_behavior) %>% mutate( total_intervals = sum(n), occurrence_rate = n / total_intervals )

ALL OCCURRENCE BEHAVIOR DATA

all_occurrence_behaviors <- olive_data %>% filter(Behavior_Channel == “All Occurrence”) %>% mutate( behavior_combined = if_else( !is.na(All_Occurrence_Behavior_Modifier_1), paste(All_Occurrence_Behavior, All_Occurrence_Behavior_Modifier_1, sep = “_“), All_Occurrence_Behavior ) )

ALL OCCURRENCE BEHAVIOR RATES

all_occurrence_rates <- all_occurrence_behaviors %>% count(behavior_combined) %>% mutate( total_events = sum(n), occurrence_rate = n / total_events )

CONTINUOUS BEHAVIOR DATA

continuous_behaviors <- olive_data %>% filter(Behavior_Channel == “Continuous”) %>% select( SessionID, Date, Time, Phase, Continuous_Channel_1_Behavior, Continuous_Channel_1_Duration_s, Continuous_Channel_2_Behavior, Continuous_Channel_2_Duration_s ) %>% pivot_longer( cols = -c(SessionID, Date, Time, Phase), names_to = c(“channel”, “.value”), names_pattern = “Continuous_Channel_(\d+)_(.*)” ) %>% filter(!is.na(Behavior), !is.na(Duration_s))

CONTINUOUS BEHAVIOR RATES

continuous_behavior_rates <- continuous_behaviors %>% group_by(Behavior) %>% summarise( total_duration_min = sum(Duration_s, na.rm = TRUE) / 60, n_sessions = n_distinct(SessionID), minutes_per_hour = (total_duration_min / n_sessions) * 2, # scale 30-min session to per-hour percent_of_hour = (minutes_per_hour / 60) * 100, .groups = “drop” )

BETWEEN PHASES DESCRIPTIVES

SCAN BEHAVIORS BETWEEN PHASES

scan_behavior_phase <- scan_behaviors %>% group_by(Phase, scan_behavior) %>% summarise(n = n(), .groups = “drop”) %>% group_by(Phase) %>% mutate( total_intervals = sum(n), occurrence_rate = n / total_intervals ) %>% ungroup()

OCCURRENCES PER HOUR

scan_behavior_phase <- scan_behavior_phase %>% mutate( occurrences_per_hour = occurrence_rate * 120 )

ALL OCCURRENCE BEHAVIORS BETWEEN PHASES

all_occurrence_phase <- all_occurrence_behaviors %>% group_by(SessionID, Phase, All_Occurrence_Behavior) %>% summarise(n = n(), .groups = “drop”) %>% # 30min -> 1hr mutate(events_per_hour = n * 2)

AVG RATE BETWEEN PHASES

all_occurrence_avg <- all_occurrence_phase %>% group_by(Phase, All_Occurrence_Behavior) %>% summarise( mean_events_per_hour = mean(events_per_hour), .groups = “drop” )

CONTINUOUS BEHAVIORS BETWEEN PHASES

continuous_behavior_phase <- continuous_behaviors %>% group_by(Phase, Behavior) %>% summarise( total_duration_min = sum(Duration_s, na.rm = TRUE) / 60, n_sessions = n_distinct(SessionID), minutes_per_hour = (total_duration_min / n_sessions) * 2, .groups = “drop” ) %>% ungroup()

DURATION PER HOUR

HUMAN PRESENCE DESCRIPTIVES

#Human presence by phase humans_by_phase <- olive_data %>% group_by(Phase) %>% summarise( total_intervals = n(), human_occurrences = sum(!is.na(Human_Present_Win_5BL)), occurrence_rate = mean(!is.na(Human_Present_Win_5BL)), .groups = “drop” )

PROXIMITY DESCRIPTIVES (PHASE 3)

Filter Phase 3 data

P3_proximity <- olive_data %>% filter(Phase == 3)

P3_proximity <- P3_proximity %>% select( SessionID, Conspecific_Proximity, BL_Dist, Video_File_Name, Date, Time, Week_Number )

BL Dist category occurrence count per week

BLDist_count <- olive_data %>% filter(Phase == 3, !is.na(BL_Dist)) %>% # remove BL_Dist NA first group_by(Week_Number, BL_Dist) %>% summarise(count = n(), .groups = “drop”) %>%

mutate( BL_Dist = factor(BL_Dist, levels = c(“Contact”, “<1 body length”, “1-5 body lengths”)),

P3_week = case_when(
  Week_Number == 20 ~ "1",
  Week_Number == 21 ~ "2",
  TRUE ~ NA_character_
)

) %>%

filter(!is.na(P3_week), !is.na(BL_Dist))

DESCRIPTIVE STAT FIGURES

SCAN BEHAVIORS BY PHASE

scan_behavior_phase %>% filter(!is.na(scan_behavior)) %>% ggplot(aes(x = Phase, y = occurrences_per_hour, fill = scan_behavior)) + geom_col(position = “dodge”) + scale_fill_viridis_d(option = “turbo”) + labs( title = “Scan Behavior Rates Between Phases”, x = “Phase”, y = “Time Spent Performing Behavior (min/hr)”, fill = “Behavior” ) + theme_minimal()

ALL OCCURRENCE BEHAVIORS BY PHASE

all_occurrence_avg %>% ggplot(aes(x = Phase, y = mean_events_per_hour, fill = All_Occurrence_Behavior)) + geom_col(position = “dodge”) + scale_fill_viridis_d(option = “turbo”) + labs( title = “Average Rate of All Occurrence Behaviors Between Phases”, x = “Phase”, y = “All Occurrence Events/hr”, fill = “Behavior” ) + theme_minimal()

CONTINUOUS BEHAVIORS BY PHASE

continuous_behavior_phase %>% filter(!is.na(Behavior)) %>% ggplot(aes(x = Phase, y = minutes_per_hour, fill = Behavior)) + geom_col(position = “dodge”) + scale_fill_viridis_d(option = “turbo”) + labs( title = “Duration of Continuous Behaviors Between Phases”, x = “Phase”, y = “Time Spent Performing Continuous Behavior (min/hr)”, fill = “Behavior” ) + theme_minimal()

PROXIMITY

BLDist_count %>% filter(!is.na(BL_Dist), !is.na(P3_week)) %>% ggplot(aes(x = BL_Dist, y = count, fill = P3_week)) + geom_col(position = “dodge”) + scale_fill_viridis_d(option = “turbo”) + labs( title = “Phase 3 Proximity Counts by Week”, x = “Distance Category”, y = “Count”, fill = “P3 Week” ) + theme_minimal()

ACTIVITY BUDGETS

CREATING SEPARATE DATASET

budget_data <- olive_data

TIME STANDARIZATION FOR EACH BEHAVIOR CHANNEL

budget_scans <- budget_data %>% filter(Behavior_Channel == “Interval”) %>% filter(!is.na(Interval_Scan_Behavior)) %>% filter(Interval_Scan_Behavior != “Out of View”) %>% mutate( behavior = Interval_Scan_Behavior, time_sec = 30 ) %>% select(behavior, time_sec)

budget_allocc <- budget_data %>% filter(Behavior_Channel == “All Occurrence”) %>% filter(!is.na(All_Occurrence_Behavior)) %>% mutate( behavior = All_Occurrence_Behavior, time_sec = 1 ) %>% select(behavior, time_sec)

budget_continuous_raw <- budget_data %>% filter(Behavior_Channel == “Continuous”)

continuous_long_1 <- budget_continuous_raw %>% transmute( behavior = Continuous_Channel_1_Behavior, time_sec = Continuous_Channel_1_Duration_s ) %>% filter(!is.na(behavior), !is.na(time_sec))

continuous_long_2 <- budget_continuous_raw %>% transmute( behavior = Continuous_Channel_2_Behavior, time_sec = Continuous_Channel_2_Duration_s ) %>% filter(!is.na(behavior), !is.na(time_sec))

BETWEEN PHASES ACTIVITY

ADDING PHASE TO SCAN BEHAVIOR BUDGET

budget_scans_phase <- budget_data %>% filter(Behavior_Channel == “Interval”) %>% filter(!is.na(Interval_Scan_Behavior)) %>% filter(Interval_Scan_Behavior != “Out of View”) %>% mutate( behavior = Interval_Scan_Behavior, time_sec = 30 ) %>% select(Phase, behavior, time_sec)

ADDING PHASE TO ALL OCCURRENCE BEHAVIOR BUDGET

budget_allocc_phase <- budget_data %>% filter(Behavior_Channel == “All Occurrence”) %>% filter(!is.na(All_Occurrence_Behavior)) %>% mutate( behavior = All_Occurrence_Behavior, time_sec = 1 ) %>% select(Phase, behavior, time_sec)

ADDING PHASE TO CONTINUOUS BEHAVIOR BUDGET

continuous_long_1 <- budget_continuous_raw %>% transmute( Phase, behavior = Continuous_Channel_1_Behavior, time_sec = Continuous_Channel_1_Duration_s ) %>% filter(!is.na(behavior), !is.na(time_sec))

continuous_long_2 <- budget_continuous_raw %>% transmute( Phase, behavior = Continuous_Channel_2_Behavior, time_sec = Continuous_Channel_2_Duration_s ) %>% filter(!is.na(behavior), !is.na(time_sec))

COMBINING CHANNELS BETWEEN PHASES

budget_continuous <- bind_rows(continuous_long_1, continuous_long_2)

budget_combined_phase <- bind_rows( budget_scans_phase, budget_allocc_phase, budget_continuous )

CALCULATING SPECIFIC BEHAVIOR PROPORTIONS BETWEEN PHASES

budget_phase_summary <- budget_combined_phase %>% group_by(Phase, behavior) %>% summarise( total_time = sum(time_sec), .groups = “drop” ) %>% group_by(Phase) %>% mutate( proportion = total_time / sum(total_time) ) %>% ungroup()

VISUALIZATION OF ALL BEHAVIORS BETWEEN PHASES

ggplot(budget_phase_summary, aes(x = ““, y = proportion, fill = behavior)) + geom_col(width = 1) + coord_polar(theta =”y”) + facet_wrap(~ Phase) +

# ADD LABELS geom_text( aes(label = ifelse(proportion > 0.10, scales::percent(proportion, accuracy = 0.1), ““)), position = position_stack(vjust = 0.5), size = 3 ) +

scale_fill_viridis_d(option = “turbo”) + theme_void() + labs( title = “Activity Budget Between Phases (All Behavior Channels Combined)”, fill = “Behavior” )

SCAN BUDGET BETWEEN PHASES

SCAN PROPORTIONS BETWEEN PHASES

scan_plot_data <- budget_scans_phase %>% group_by(Phase, behavior) %>% summarise(n = n(), .groups = “drop”) %>% group_by(Phase) %>% mutate( proportion = n / sum(n), percent = proportion * 100, label_inside = ifelse(percent > 5, paste0(round(percent, 1), “%”), NA), label_outside = ifelse(percent <= 5, paste0(behavior, ” (“, round(percent, 1),”%)“), NA) ) %>% ungroup()

VISUZALIZATION OF SCAN BEHAVIOR PROPORTIONS BETWEEN PHASES

ggplot(scan_plot_data, aes(x = 1, y = proportion, fill = behavior)) + geom_col(width = 1) + coord_polar(theta = “y”) + facet_wrap(~ Phase) + scale_fill_viridis_d(option = “turbo”) +

geom_text(aes(label = label_inside), position = position_stack(vjust = 0.5), color = “black”, size = 4, na.rm = TRUE) +

guides(fill = guide_legend(title = “Behavior”)) +

labs( title = “Scan Behavior Budget Between Phases”, fill = “Behavior” ) + theme_void()

ALL OCCURRENCE AND CONTINUOUS BETWEEN PHASES

COMBINING ALL OCCURRENCE AND CONTINUOUS DATA

budget_allocc_cont <- bind_rows( budget_allocc_phase, budget_continuous )

CALCULATING PROPORTIONS

allocc_cont_plot_data <- budget_allocc_cont %>% group_by(Phase, behavior) %>% summarise(total_time = sum(time_sec), .groups = “drop”) %>% group_by(Phase) %>% mutate( proportion = total_time / sum(total_time), percent = proportion * 100, label_inside = ifelse(percent > 5, paste0(round(percent, 1), “%”), NA), label_outside = ifelse(percent <= 5, paste0(behavior, ” (“, round(percent, 1),”%)“), NA) ) %>% ungroup()

VISUALIZATION OF ALL OCCURRENCE AND CONTINUOUS BUDGETS ACROSS PHASES

ggplot(allocc_cont_plot_data, aes(x = 1, y = proportion, fill = behavior)) + geom_col(width = 1) + coord_polar(theta = “y”) + facet_wrap(~ Phase) + scale_fill_viridis_d(option = “turbo”) +

geom_text(aes(label = label_inside), position = position_stack(vjust = 0.5), color = “black”, size = 4, na.rm = TRUE) +

labs( title = “Stress-related Budget Between Phases”, fill = “Behavior” ) + theme_void()

SCAN BUDGET ACROSS ALL PHASES

SCAN PROPORTIONS

scan_plot_data <- budget_scans %>% group_by(behavior) %>% summarise( n = n(), .groups = “drop” ) %>% mutate( proportion = n / sum(n) )

VISUALIZATION

ggplot(scan_plot_data, aes(x = ““, y = proportion, fill = behavior)) + geom_col(width = 1) + coord_polar(theta =”y”) + scale_fill_viridis_d(option = “turbo”) + labs( title = “Activity Budget: Interval Scan Behaviors”, fill = “Behavior” ) + theme_void() +

geom_text( aes(label = scales::percent(proportion, accuracy = 0.1)), position = position_stack(vjust = 0.5), size = 3 )

ALL OCCURRENCE BUDGET (POTENTIALLY REMOVE)

ALL OCCURRENCE PROPORTIONS

allocc_plot_data <- budget_allocc %>% group_by(behavior) %>% summarise( total_time = sum(time_sec), .groups = “drop” ) %>% mutate( proportion = total_time / sum(total_time) )

VISUALIZATION

ggplot(allocc_plot_data, aes(x = ““, y = proportion, fill = behavior)) + geom_col(width = 1) + coord_polar(theta =”y”) + scale_fill_viridis_d(option = “turbo”) + theme_void() + labs( title = “Activity Budget: All Occurrence Behaviors”, fill = “Behavior” )

CONTINUOUS BUDGET

COMBINING CONTINUOUS CHANNELS

budget_continuous <- bind_rows(continuous_long_1, continuous_long_2)

CONTINUOUS PROPORTIONS

continuous_plot_data <- budget_continuous %>% group_by(behavior) %>% summarise( total_time = sum(time_sec), .groups = “drop” ) %>% mutate( proportion = total_time / sum(total_time) )

VISUALIZATION

ggplot(continuous_plot_data, aes(x = ““, y = proportion, fill = behavior)) + geom_col(width = 1) + coord_polar(theta =”y”) + scale_fill_viridis_d(option = “turbo”) + theme_void() + labs( title = “Activity Budget: Continuous Behaviors”, fill = “Behavior” )

COMBINING ALL CHANNELS

budget_combined <- bind_rows( budget_scans, budget_allocc, budget_continuous )

SUMMARIZING BUDGET

budget_summary <- budget_combined %>% group_by(behavior) %>% summarise( total_time = sum(time_sec), .groups = “drop” ) %>% mutate( proportion = total_time / sum(total_time) )

VISUALIZATION

ggplot(budget_summary, aes(x = ““, y = proportion, fill = behavior)) + geom_col(width = 1) + coord_polar(theta =”y”) + scale_fill_viridis_d(option = “turbo”) + theme_void() + labs( title = “Activity Budget (All Behavior Channels Combined)”, fill = “Behavior” )