Statistical analysis

Chronic stress raises and vocal plasticity in budgerigars

Author
Published

December 16, 2025

Data analysis for the paper

Timothy F. Wright, Marcelo Araya-Salas, Alondra Villalba, Amelia M.-F. Clayshulte Abraham, Carlos I. Campos, Amanda L. Schmidt, Connor Draney, Jodie M. Jawor. In review. Chronic stress raises baseline circulating corticosterone and reduces vocal plasticity in male budgerigars, an avian model for adult vocal learning.

All data and source code is also found at: https://github.com/maRce10/budgie-stress-and-vocal-learning

 

0.1 Load packages

Code
# install 'sketchy' if not install yet
if (!requireNamespace("sketchy", quietly = TRUE)) {
    install.packages("sketchy")
}

## add 'developer' to packages to be installed from github
x <- c("remotes", "readxl", "pbapply", "viridis", "ggplot2", "kableExtra",
    "knitr", "formatR", "MASS", "brms", "lme4", "cowplot", "maRce10/PhenotypeSpace",
    "maRce10/brmsish", "corrplot")

sketchy::load_packages(x)


# funnction to print tables in html format
print_kable <- function(x) {
    kb <- kable(x, row.names = TRUE, digits = 4, "html")
    kb <- kable_styling(kb, bootstrap_options = c("striped", "hover",
        "condensed", "responsive"))
    scroll_box(kb, width = "100%")
}

0.2 Functions and global parameters

Code
opts_knit$set(root.dir = "..")

# set evaluation false
opts_chunk$set(fig.width = 10, fig.height = 6, warning = FALSE, message = FALSE,
    tidy = TRUE)

read_excel_df <- function(...) data.frame(read_excel(...))


# for reading months in english format
sl <- Sys.setlocale(locale = "en_US.UTF-8")


standard_error <- function(x) sd(x)/sqrt(length(x))

cols <- viridis(10, alpha = 0.7)

col_pointrange <- cols[7]

# make color scale
colorrange <- colorRampPalette(c("skyblue", "white", "tomato"))(10)
colorrange2 <- colorRampPalette(c("skyblue", "gray", "tomato"))(10)

colorrange <- colorRampPalette(c("#440154FF", "white", "#21908CFF"))(10)
colorrange2 <- colorRampPalette(c("#440154FF", "gray", "#21908CFF"))(10)


bs <- if (isTRUE(getOption("knitr.in.progress"))) 10 else 20

Modify these paths to point to the data directories

Code
raw_data_path <- "./data/raw/"
processed_data_path <- "./data/processed/"
output_path <- "./output"
Code
# read ext sel tab calls
sels <- read.csv(file.path(raw_data_path, "acoustic_features_budgie_calls.csv"))

# keep only spectrographic parameters
sels <- sels[, c("sound.files", "selec", "duration", "meanfreq", "sd",
    "freq.median", "freq.IQR", "time.IQR", "skew", "kurt", "sp.ent",
    "time.ent", "entropy", "meandom", "mindom", "maxdom", "dfrange",
    "modindx", "meanpeakf")]

sels$ID <- sapply(sels$sound.files, function(x) strsplit(x, "_")[[1]][1])
sels$month <- sapply(sels$sound.files, function(x) strsplit(x, "_")[[1]][2])
sels$day <- sapply(sels$sound.files, function(x) strsplit(x, "_")[[1]][3])
sels$year <- sapply(sels$sound.files, function(x) strsplit(x, "_")[[1]][4])

sels$date <- paste(sels$day, substr(sels$month, 0, 3), sels$year,
    sep = "-")

sels$date <- as.Date(sels$date, format = "%d-%b-%Y")

# acoustic measurements
areas_by_week <- read.csv(file.path(processed_data_path, "acoustic_space_area_by_id_and_week.csv"))


indiv_ovlp <- read.csv(file.path(processed_data_path, "acoustic_space_density_overlap_to_first_week_by_id.csv"))

indiv_ovlp$treatment <- factor(indiv_ovlp$treatment, levels = c("Control",
    "Medium Stress", "High Stress"))

group_ovlp <- read.csv(file.path(processed_data_path, "acoustic_space_density_overlap_to_group_by_week_id.csv"))


group_ovlp$treatment <- factor(group_ovlp$treatment, levels = c("Control",
    "Medium Stress", "High Stress"))

1 Format data

Code
metadat <- read_excel_df(file.path(raw_data_path, "experiment_metadata.xlsx"))

sels$ID[sels$ID == "125YGMM"] <- "125YGHM"
sels$ID[sels$ID == "394YBHM"] <- "394WBHM"


sels$treatment <- sapply(1:nrow(sels), function(x) {
    metadat$Treatment[metadat$Bird.ID == sels$ID[x]][1]

})


sels$treatment.room <- sapply(1:nrow(sels), function(x) {
    metadat$Treatment.Room[metadat$Bird.ID == sels$ID[x]][1]

})


sels$round <- sapply(1:nrow(sels), function(x) {
    metadat$Round[metadat$Bird.ID == sels$ID[x]][1]

})

sels$source.room <- sapply(1:nrow(sels), function(x) {
    metadat$Source.Room[metadat$Bird.ID == sels$ID[x]][1]

})

sels$record.group <- sapply(1:nrow(sels), function(x) {
    metadat$Record.Group[metadat$Bird.ID == sels$ID[x]][1]

})


# add week
out <- lapply(unique(sels$round), function(x) {
    Y <- sels[sels$round == x, ]

    min_date <- min(Y$date)
    week_limits <- min_date + seq(0, 100, by = 7)

    Y$week <- NA
    for (i in 2:length(week_limits)) Y$week[Y$date >= week_limits[i -
        1] & Y$date < week_limits[i]] <- i - 1

    return(Y)
})

sels <- do.call(rbind, out)


sels$cort.baseline <- sapply(1:nrow(sels), function(x) {
    if (sels$week[x] == 1)
        out <- metadat$D3.CORT.Baseline[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 2)
        out <- metadat$D7.CORT.Baseline[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 3)
        out <- metadat$D14.CORT.Baseline[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 4)
        out <- metadat$D21.CORT.Baseline[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 5)
        out <- metadat$D28.CORT.Baseline[metadat$Bird.ID == sels$ID[x]][1]

    return(out)
})


sels$cort.stress <- sapply(1:nrow(sels), function(x) {
    if (sels$week[x] == 1)
        out <- metadat$D3.CORT.Stress[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 2)
        out <- metadat$D7.CORT.Stress[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 3)
        out <- metadat$D14.CORT.Stress[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 4)
        out <- metadat$D21.CORT.Stress[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 5)
        out <- metadat$D28.CORT.Stress[metadat$Bird.ID == sels$ID[x]][1]

    return(out)
})

sels$stress.response <- sels$cort.stress  #- sels$cort.baseline

sels$weight <- sapply(1:nrow(sels), function(x) {
    if (sels$week[x] == 1)
        out <- metadat$D3.Bird.Weight..g.[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 2)
        out <- metadat$D7.Bird.Weight..g.[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 3)
        out <- metadat$D14.Bird.Weight..g.[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 4)
        out <- metadat$D21.Bird.Weight..g.[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 5)
        out <- metadat$D28.Bird.Weight..g.[metadat$Bird.ID == sels$ID[x]][1]

    return(out)
})


sels$breath.count <- sapply(1:nrow(sels), function(x) {
    if (sels$week[x] == 1)
        out <- metadat$D3.Breath.Count[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 2)
        out <- metadat$D7.Breath.Count[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 3)
        out <- metadat$D14.Bird.Weight..g.[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 4)
        out <- metadat$D21.Bird.Weight..g.[metadat$Bird.ID == sels$ID[x]][1]

    if (sels$week[x] == 5)
        out <- metadat$D28.Bird.Weight..g.[metadat$Bird.ID == sels$ID[x]][1]

    return(out)
})


# remove week 5
sels <- sels[sels$week != 5, ]

foxp2 <- read.csv(file.path(raw_data_path, "INBREmale_IHCCounts_FINAL_5Dec25.csv"))

foxp2$Treatment[grep("HIGH", foxp2$Treatment)] <- "High stress"
foxp2$Treatment[grep("Control", foxp2$Treatment, ignore.case = T)] <- "Control"
foxp2$Treatment[grep("MED", foxp2$Treatment)] <- "Medium stress"

foxp2$Treatment <- factor(foxp2$Treatment, levels = c("Control", "Medium stress",
    "High stress"))
Code
agg_dat <- aggregate(selec ~ ID + week, data = sels, length)

# without comparing to week 1
agg_dat$call.count <- sapply(1:nrow(agg_dat), function(x) agg_dat$selec[x])

agg_dat$selec <- NULL

agg_dat$baseline.CORT <- sapply(1:nrow(agg_dat), function(x) {
    baseline <- sels$cort.baseline[sels$week == 1 & sels$ID == agg_dat$ID[x]]
    current <- sels$cort.baseline[sels$week == agg_dat$week[x] & sels$ID ==
        agg_dat$ID[x]]

    if (length(baseline) > 0 & length(current) > 0)
        change <- mean(current) - mean(baseline) else change <- NA

    return(change)
})

agg_dat$stress.response <- sapply(1:nrow(agg_dat), function(x) {
    baseline <- sels$stress.response[sels$week == 1 & sels$ID == agg_dat$ID[x]]
    current <- sels$stress.response[sels$week == agg_dat$week[x] &
        sels$ID == agg_dat$ID[x]]

    if (length(baseline) > 0 & length(current) > 0)
        change <- mean(current) - mean(baseline) else change <- NA

    return(change)
})


agg_dat$stress.CORT <- sapply(1:nrow(agg_dat), function(x) {
    baseline <- sels$cort.stress[sels$week == 1 & sels$ID == agg_dat$ID[x]]
    current <- sels$cort.stress[sels$week == agg_dat$week[x] & sels$ID ==
        agg_dat$ID[x]]

    if (length(baseline) > 0 & length(current) > 0)
        change <- mean(current) - mean(baseline) else change <- NA

    return(change)
})

agg_dat$weight <- sapply(1:nrow(agg_dat), function(x) {
    baseline <- sels$weight[sels$week == 1 & sels$ID == agg_dat$ID[x]]
    current <- sels$weight[sels$week == agg_dat$week[x] & sels$ID ==
        agg_dat$ID[x]]

    if (length(baseline) > 0 & length(current) > 0)
        change <- mean(current) - mean(baseline) else change <- NA

    return(change)
})

agg_dat$breath.rate <- sapply(1:nrow(agg_dat), function(x) {
    baseline <- sels$breath.count[sels$week == 1 & sels$ID == agg_dat$ID[x]]
    current <- sels$breath.count[sels$week == agg_dat$week[x] & sels$ID ==
        agg_dat$ID[x]]

    if (length(baseline) > 0 & length(current) > 0)
        change <- mean(current) - mean(baseline) else change <- NA

    return(change)
})

agg_dat$acoustic.diversity <- sapply(1:nrow(agg_dat), function(x) {
    area <- areas_by_week$raref.area[areas_by_week$ID == agg_dat$ID[x] &
        areas_by_week$week == agg_dat$week[x]]

    if (length(area) < 1)
        area <- NA

    return(area)
})

agg_dat$acoustic.distance <- sapply(1:nrow(agg_dat), function(x) {
    distance <- indiv_ovlp$distance.to.first.week[indiv_ovlp$ID ==
        agg_dat$ID[x] & indiv_ovlp$week == agg_dat$week[x]]

    if (length(distance) < 1)
        distance <- NA

    return(distance)
})

agg_dat$acustic.plasticity <- sapply(1:nrow(agg_dat), function(x) {
    overlap <- indiv_ovlp$overlap.to.first.week[indiv_ovlp$ID == agg_dat$ID[x] &
        indiv_ovlp$week == agg_dat$week[x]]

    plasticity <- 1 - overlap

    if (length(plasticity) < 1)
        plasticity <- NA

    return(plasticity)
})

agg_dat$acoustic.convergence <- sapply(1:nrow(agg_dat), function(x) {
    overlap <- group_ovlp$overlap.to.group[group_ovlp$ID == agg_dat$ID[x] &
        group_ovlp$week == agg_dat$week[x]]

    if (length(overlap) < 1)
        overlap <- NA

    return(overlap)
})


agg_dat$treatment <- sapply(1:nrow(agg_dat), function(x) unique(sels$treatment[sels$ID ==
    agg_dat$ID[x]]))

agg_dat$round <- sapply(1:nrow(agg_dat), function(x) unique(sels$round[sels$ID ==
    agg_dat$ID[x]]))


agg_dat$foxp2 <- sapply(1:nrow(agg_dat), function(x) {
    if (agg_dat$week[x] == 4)
        fp2 <- foxp2$FoxP2.Counts.MMSt.Striatum[foxp2$Bird.ID == agg_dat$ID[x]][1] else fp2 <- NA
    if (length(fp2) == 0)
        fp2 <- NA
    return(fp2)
})

1.0.1 Correlation among variables

Only using day 4 data

Code
day4_agg <- agg_dat[agg_dat$week == 4, c("ID", "breath.rate", "weight",
    "baseline.CORT", "stress.CORT", "call.count", "acustic.plasticity",
    "acoustic.convergence", "acoustic.diversity", "foxp2")]


day4_agg$ID <- NULL

corr_mat <- cor(day4_agg, use = "pairwise.complete.obs")

pvalue_mat <- corr_mat
pvalue_mat <- pvalue_mat * NA

for (i in colnames(pvalue_mat)) {
    for (e in rownames(pvalue_mat)) {

        ct <- cor.test(x = day4_agg[, i], y = day4_agg[, e], method = "pearson",
            use = "pairwise.complete.obs")$p.value

        pvalue_mat[i, e] <- ct
        pvalue_mat[e, i] <- ct
    }
}
n_mat <- corr_mat
n_mat <- n_mat * NA

for (i in colnames(pvalue_mat)) {
    for (e in rownames(pvalue_mat)) {
        n_mat[i, e] <- sum(complete.cases(day4_agg[, i], day4_agg[,
            e]))
    }
}


# write.csv(pm, './output/parameters_correlation_pvalues.csv',
# row.names = TRUE) write.csv(pm2, './output/sample_sizes.csv',
# row.names = TRUE)

rownames(corr_mat) <- colnames(corr_mat) <- names(day4_agg) <- c("Breath\nrate",
    "Weight", "Baseline\nCORT", "Stress\nCORT", "Vocal\noutput", "Vocal\nplasticity",
    "Vocal\nconvergence", "Vocal\ndiversity", "FOXP2")


corrplot.mixed(corr_mat, pch = "x", pch.col = "gray", pch.cex = 0.9,
    upper = "ellipse", lower = "number", tl.col = "black", tl.pos = "lt",
    number.cex = 0.7, tl.cex = 0.7, order = "original", mar = c(1,
        1, 1, 1), upper.col = colorrange, lower.col = colorrange2)

Code
if (!isTRUE(getOption("knitr.in.progress"))) {
    dev.copy(png, file.path(output_path, "variable_colinearity.png"),
        width = 1700, height = 1500, res = 300)
    dev.off()  # Close the graphics device
}

2 Physiological parameters

2.1 Stats

Models: Predicted physio measure ~ treatment + week (continuous) + IndRandom

Variables (Difference from Week 1): weight, BR, baseline CORT, Stress CORT, Stress Response

Code
responses <- c("baseline.CORT", "stress.response", "stress.CORT",
    "weight", "breath.rate")

predictors <- c("~ treatment + week + (1|ID) + (1|round)")

formulas <- expand.grid(responses = responses, predictors = predictors,
    stringsAsFactors = FALSE)

vars_to_scale <- c(responses, "week")

# remove week 1
sub_agg_dat <- agg_dat[agg_dat$week != 1, ]

for (i in vars_to_scale) sub_agg_dat[, vars_to_scale] <- scale(sub_agg_dat[,
    vars_to_scale])

physio_models <- lapply(1:nrow(formulas), function(x) {
    sub_dat <- sub_agg_dat[!is.na(sub_agg_dat[names(sub_agg_dat) ==
        formulas$responses[x]]), ]
    sub_dat
    # replace ~ by 'by' in the formula
    mod_name <- paste(formulas$responses[x], gsub("~", "by", formulas$predictors[x]))

    mod <- brm(formula = paste(formulas$responses[x], formulas$predictors[x]),
        iter = 1e+05, silent = 2, family = student(), data = sub_dat,
        control = list(adapt_delta = 0.9, max_treedepth = 15), chains = 4,
        cores = 4, file = paste0(file.path(processed_data_path, "physio-"),
            mod_name), file_refit = "always", prior = c(prior(normal(0,
            5), "b"), prior(normal(0, 10), "Intercept"), prior(student_t(3,
            0, 10), "sd"), prior(student_t(3, 0, 10), "sigma")))

    return(mod)
})
Code
physio_models <- list.files(file.path(processed_data_path, "regressions"),
    pattern = "physio-", full.names = TRUE)

for (x in 1:length(physio_models)) extended_summary(read.file = physio_models[x],
    gsub.pattern = "b_treatment|b_", gsub.replacement = "", highlight = TRUE,
    remove.intercepts = TRUE)

2.2 physio-acustic.plasticity by treatment + week + (1|ID) + (1|round)

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 breath.rate ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 0 (0%) 0 282877.3 144723.3 1702562168
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
HighStress 1.563 -7.621 10.703 1 367754.7 147396.5
MediumStress -0.199 -9.468 9.053 1 368223.6 144723.3
week -16.139 -25.424 -6.599 1 282877.3 162601.3

2.3 physio-baseline.CORT by treatment + week + (1|ID) + (1|round)

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 baseline.CORT ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 6255 (0.031%) 0 8017.135 31502.5 662141751
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
HighStress 0.874 0.110 1.637 1.001 21696.113 35836.92
MediumStress 0.194 -0.620 0.995 1 25210.214 44566.31
week -0.010 -0.139 0.119 1.001 8017.135 31502.50

2.4 physio-breath.rate by treatment + week + (1|ID) + (1|round)

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 breath.rate ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 5808 (0.029%) 0 4237.78 22921.74 1411987597
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
HighStress 0.228 -0.167 0.620 1.001 6084.785 22921.74
MediumStress 0.115 -0.310 0.544 1 15827.830 87358.76
week -0.768 -0.909 -0.625 1.001 4237.780 35802.47

2.5 physio-stress.CORT by treatment + week + (1|ID) + (1|round)

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 stress.CORT ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 1796 (0.009%) 0 22431.33 5699.755 1854922145
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
HighStress -0.259 -1.044 0.529 1 22431.33 5699.755
MediumStress 0.037 -0.852 0.918 1 37367.15 70541.436
week -0.065 -0.170 0.039 1 44228.85 45826.122

2.6 physio-stress.response by treatment + week + (1|ID) + (1|round)

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 stress.response ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 4766 (0.024%) 0 4017.288 4369.013 1337746393
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
HighStress -0.244 -1.037 0.553 1.001 8303.060 6123.450
MediumStress 0.048 -0.840 0.917 1.002 4017.288 4369.013
week -0.064 -0.168 0.038 1.001 4332.610 8721.908

2.7 physio-weight by treatment + week + (1|ID) + (1|round)

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 weight ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 4876 (0.024%) 0 1595.299 536.633 1479872948
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
HighStress -0.400 -1.185 0.399 1.002 4731.667 36350.344
MediumStress -0.166 -1.031 0.706 1.001 22880.693 69798.743
week -0.085 -0.210 0.039 1.003 1595.299 536.633

Code
physio_model_list <- list.files(file.path(processed_data_path, "regressions"),
    pattern = "physio-", full.names = TRUE)

# read all physio models
physio_models <- lapply(physio_model_list, readRDS)
names(physio_models) <- gsub(".rds", "", basename(physio_model_list))

breath.count <- stack(metadat[, c("D3.Breath.Count", "D7.Breath.Count",
    "D14.Breath.Count", "D21.Breath.Count", "D28.Breath.Count")])

weight <- stack(metadat[, c("D3.Bird.Weight..g.", "D7.Bird.Weight..g.",
    "D14.Bird.Weight..g.", "D21.Bird.Weight..g.", "D28.Bird.Weight..g.")])

cort.stress <- stack(metadat[, c("D3.CORT.Stress", "D7.CORT.Stress",
    "D14.CORT.Stress", "D21.CORT.Stress", "D28.CORT.Stress")])

cort.baseline <- stack(metadat[, c("D3.CORT.Baseline", "D7.CORT.Baseline",
    "D14.CORT.Baseline", "D21.CORT.Baseline", "D28.CORT.Baseline")])


stress <- data.frame(metadat[, c("Bird.ID", "Treatment", "Round",
    "Treatment.Room")], week = breath.count$ind, breath.count = breath.count$values,
    weight = weight$values, cort.stress = cort.stress$values, cort.baseline = cort.baseline$values,
    stress.response = cort.stress$values - cort.baseline$values)

# head(stress)

stress$week <- factor(sapply(strsplit(as.character(stress$week), "\\."),
    "[[", 1), levels = c("D3", "D7", "D14", "D21", "D28"))

stress$day <- as.numeric(gsub("D", "", as.character(stress$week)))
stress$round <- paste("Round", stress$Round)

stress$Treatment <- gsub("Medium", "Med.", stress$Treatment)

stress$treatment <- factor(stress$Treatment, levels = c("Control",
    "Med. Stress", "High Stress"))

# remove 5th week
stress <- stress[stress$week != "D28", ]


stress_l <- lapply(stress$Bird.ID, function(x) {
    X <- stress[stress$Bird.ID == x, ]

    X$breath.count <- X$breath.count - X$breath.count[X$week == "D3"]
    X$weight <- X$weight - X$weight[X$week == "D3"]
    X$cort.stress <- X$cort.stress - X$cort.stress[X$week == "D3"]
    X$cort.baseline <- X$cort.baseline - X$cort.baseline[X$week ==
        "D3"]
    X$stress.response <- X$stress.response - X$stress.response[X$week ==
        "D3"]

    return(X)
})

stress <- do.call(rbind, stress_l)

agg_stress <- aggregate(cbind(breath.count, weight, stress.response,
    cort.baseline) ~ week + treatment, stress, mean)
agg_stress_se <- aggregate(cbind(breath.count, weight, stress.response,
    cort.baseline) ~ week + treatment, stress, standard_error)

names(agg_stress_se) <- paste(names(agg_stress_se), ".se", sep = "")

agg_stress <- cbind(agg_stress, agg_stress_se[, 3:6])

agg_stress$Week <- 1:4


gg_coeffs_physio <- lapply(physio_models, function(x) {
    vars <- grep("b_", posterior::variables(x), value = TRUE)
    draws <- posterior::as_draws_array(x, variable = vars)

    coef_table <- brmsish:::draw_summary(draws, variables = vars,
        probs = c(0.025, 0.975), robust = TRUE, spread.type = "HPDI")

    coef_table$predictor <- rownames(coef_table)
    coef_table$predictor <- gsub("b_treatment|b_", "", coef_table$predictor)
    coef_table$predictor <- gsub("Stress", " stress", coef_table$predictor)
    coef_table$predictor <- gsub("week", "Week", coef_table$predictor)
    coef_table$predictor <- gsub("Medium", "Med.", coef_table$predictor)

    coef_table <- coef_table[coef_table$predictor != "Intercept",
        ]

    gg_coef <- ggplot2::ggplot(data = coef_table, aes(x = Estimate,
        y = predictor)) + geom_vline(xintercept = 0, lty = 2) + ggplot2::geom_point(size = 3,
        col = col_pointrange) + ggplot2::geom_errorbar(ggplot2::aes(xmin = `l-95% CI`,
        xmax = `u-95% CI`), width = 0, col = col_pointrange) + ggplot2::theme_classic(base_size = bs) +
        ggplot2::theme(axis.ticks.length = ggplot2::unit(0, "pt"),
            plot.margin = ggplot2::margin(0, 0, 0, 0, "pt"), legend.position = "none",
            strip.background = ggplot2::element_blank(), strip.text = ggplot2::element_blank()) +
        ggplot2::labs(x = "Effect size", y = "")

    return(gg_coef)
})

Violin plots, mean and SE, and effect size graph

Code
# physio_model_list <- list.files(
# file.path(processed_data_path, 'regressions'), pattern =
# 'physio-', full.names = TRUE ) # read all physio models
# physio_models <- lapply(physio_model_list, readRDS)
# names(physio_models) <- gsub('.rds', '',
# basename(physio_model_list))

breath.count <- stack(metadat[, c("D3.Breath.Count", "D7.Breath.Count",
    "D14.Breath.Count", "D21.Breath.Count", "D28.Breath.Count")])

weight <- stack(metadat[, c("D3.Bird.Weight..g.", "D7.Bird.Weight..g.",
    "D14.Bird.Weight..g.", "D21.Bird.Weight..g.", "D28.Bird.Weight..g.")])

cort.stress <- stack(metadat[, c("D3.CORT.Stress", "D7.CORT.Stress",
    "D14.CORT.Stress", "D21.CORT.Stress", "D28.CORT.Stress")])

cort.baseline <- stack(metadat[, c("D3.CORT.Baseline", "D7.CORT.Baseline",
    "D14.CORT.Baseline", "D21.CORT.Baseline", "D28.CORT.Baseline")])


stress <- data.frame(metadat[, c("Bird.ID", "Treatment", "Round",
    "Treatment.Room")], week = breath.count$ind, breath.count = breath.count$values,
    weight = weight$values, cort.stress = cort.stress$values, cort.baseline = cort.baseline$values,
    stress.response = cort.stress$values - cort.baseline$values)

# head(stress)

stress$week <- factor(sapply(strsplit(as.character(stress$week), "\\."),
    "[[", 1), levels = c("D3", "D7", "D14", "D21", "D28"))

stress$day <- as.numeric(gsub("D", "", as.character(stress$week)))
stress$round <- paste("Round", stress$Round)

stress$Treatment <- gsub("Medium", "Med.", stress$Treatment)

stress$treatment <- factor(stress$Treatment, levels = c("Control",
    "Med. Stress", "High Stress"))

# remove 5th week
stress <- stress[stress$week != "D28", ]

stress$Week <- as.character(as.numeric(stress$week))

stress_l <- lapply(stress$Bird.ID, function(x) {
    X <- stress[stress$Bird.ID == x, ]

    X$breath.count <- X$breath.count - X$breath.count[X$week == "D3"]
    X$weight <- X$weight - X$weight[X$week == "D3"]
    X$cort.stress <- X$cort.stress - X$cort.stress[X$week == "D3"]
    X$cort.baseline <- X$cort.baseline - X$cort.baseline[X$week ==
        "D3"]
    X$stress.response <- X$stress.response - X$stress.response[X$week ==
        "D3"]

    return(X)
})

stress <- do.call(rbind, stress_l)

agg_stress <- aggregate(cbind(breath.count, weight, stress.response,
    cort.baseline) ~ week + treatment, stress, mean)
agg_stress_se <- aggregate(cbind(breath.count, weight, stress.response,
    cort.baseline) ~ week + treatment, stress, standard_error)

names(agg_stress_se) <- paste(names(agg_stress_se), ".se", sep = "")


agg_stress <- cbind(agg_stress, agg_stress_se[, 3:6])

agg_stress$Week <- 1:4


agg_stress$breath.count[agg_stress$Week == 1] <- NA
agg_stress$weight[agg_stress$Week == 1] <- NA
agg_stress$cort.baseline[agg_stress$Week == 1] <- NA
agg_stress$stress.response[agg_stress$Week == 1] <- NA
stress$breath.count[stress$Week == 1] <- NA
stress$weight[stress$Week == 1] <- NA
stress$cort.baseline[stress$Week == 1] <- NA
stress$stress.response[stress$Week == 1] <- NA

gg_breath.count <- ggplot(data = stress, aes(x = Week, y = breath.count,
    fill = treatment)) + geom_violin(scale = "width") + geom_point(position = position_jitter(width = 0.1),
    alpha = 0.5, size = 1) + scale_fill_viridis_d(begin = 0.1, end = 0.9,
    alpha = 0.9) + facet_wrap(~treatment, ncol = 3, scale = "fixed") +
    labs(y = "Mean change in breath\nrate (breaths/min)", x = "Week") +
    theme_classic(base_size = bs) + theme(legend.position = "none") +
    geom_errorbar(data = agg_stress, aes(x = Week, y = breath.count,
        ymin = breath.count - breath.count.se, ymax = breath.count +
            breath.count.se), width = 0, color = "white", size = 1.5) +
    geom_point(data = agg_stress, aes(x = Week, y = breath.count),
        fill = "white", size = 3, pch = 21)


gg_weight <- ggplot(data = stress, aes(x = Week, y = weight, fill = treatment)) +
    geom_violin(scale = "width") + geom_point(position = position_jitter(width = 0.1),
    alpha = 0.5, size = 1) + scale_fill_viridis_d(begin = 0.1, end = 0.9,
    alpha = 0.9) + facet_wrap(~treatment, ncol = 3, scale = "fixed") +
    labs(y = "Mean change in \nweight (g)", x = "Week") + theme_classic(base_size = bs) +
    theme(legend.position = "none") + geom_errorbar(data = agg_stress,
    aes(x = Week, y = weight, ymin = weight - weight.se, ymax = weight +
        weight.se), width = 0, color = "white", size = 1.5) + geom_point(data = agg_stress,
    aes(x = Week, y = weight, fill = treatment), fill = "white", size = 3,
    pch = 21)


gg_cort.baseline <- ggplot(data = stress, aes(x = Week, y = cort.baseline,
    fill = treatment)) + geom_violin(scale = "width") + geom_point(position = position_jitter(width = 0.1),
    alpha = 0.5, size = 1) + scale_fill_viridis_d(begin = 0.1, end = 0.9,
    alpha = 0.9) + facet_wrap(~treatment, ncol = 3, scale = "fixed") +
    labs(y = "Mean change in \nbaseline CORT (ng/mL)", x = "Week") +
    theme_classic(base_size = bs) + theme(legend.position = "none") +
    geom_errorbar(data = agg_stress, aes(x = Week, y = cort.baseline,
        ymin = cort.baseline - cort.baseline.se, ymax = cort.baseline +
            cort.baseline.se), width = 0, color = "white", size = 1.5) +
    geom_point(data = agg_stress, aes(x = Week, y = cort.baseline,
        fill = treatment), fill = "white", size = 3, pch = 21)

gg_stress.response <- ggplot(data = stress, aes(x = Week, y = stress.response,
    fill = treatment)) + geom_violin(scale = "width") + geom_point(position = position_jitter(width = 0.1),
    alpha = 0.5, size = 1) + scale_fill_viridis_d(begin = 0.1, end = 0.9,
    alpha = 0.9) + facet_wrap(~treatment, ncol = 3, scale = "fixed") +
    labs(y = "Mean change in stress\nresponse CORT (ng/mL)", x = "Week") +
    theme_classic(base_size = bs) + theme(legend.position = "none") +
    geom_errorbar(data = agg_stress, aes(x = Week, y = stress.response,
        ymin = stress.response - stress.response.se, ymax = stress.response +
            stress.response.se), width = 0, color = "white", size = 1.5) +
    geom_point(data = agg_stress, aes(x = Week, y = stress.response,
        fill = treatment), fill = "white", size = 3, pch = 21)


# gg_coeffs_physio <- lapply(physio_models, function(x) { vars
# <- grep('b_', posterior::variables(x), value = TRUE) draws <-
# posterior::as_draws_array(x, variable = vars) coef_table <-
# brmsish:::draw_summary( draws, variables = vars, probs =
# c(0.025, 0.975), robust = TRUE, spread.type = 'HPDI' )
# coef_table$predictor <- rownames(coef_table)
# coef_table$predictor <- gsub('b_treatment|b_', '',
# coef_table$predictor) coef_table$predictor <- gsub('Stress', '
# stress', coef_table$predictor) coef_table$predictor <-
# gsub('week', 'Week', coef_table$predictor) coef_table <-
# coef_table[coef_table$predictor != 'Intercept', ] gg_coef <-
# ggplot2::ggplot(data = coef_table, aes(x = Estimate, y =
# predictor)) + geom_vline(xintercept = 0, lty = 2) +
# ggplot2::geom_point(size = 3, col = col_pointrange) +
# ggplot2::geom_errorbar( ggplot2::aes(xmin = `l-95% CI`, xmax =
# `u-95% CI`), width = 0, col = col_pointrange ) +
# ggplot2::theme_classic(base_size = bs) + ggplot2::theme(
# axis.ticks.length = ggplot2::unit(0, 'pt'), plot.margin =
# ggplot2::margin(0, 0, 0, 0, 'pt'), legend.position = 'none',
# strip.background = ggplot2::element_blank(), strip.text =
# ggplot2::element_blank() ) + ggplot2::labs(x = 'Effect size',
# y = '') return(gg_coef) })

cowplot::plot_grid(gg_breath.count, gg_weight, gg_cort.baseline, gg_stress.response,
    gg_coeffs_physio[[grep("breath", names(gg_coeffs_physio))]] +
        theme_classic(base_size = bs), gg_coeffs_physio[[grep("weight",
        names(gg_coeffs_physio))]] + theme_classic(base_size = bs),
    gg_coeffs_physio[[grep("baseline", names(gg_coeffs_physio))]] +
        theme_classic(base_size = bs), gg_coeffs_physio[[grep("response",
        names(gg_coeffs_physio))]] + theme_classic(base_size = bs),
    nrow = 2, rel_heights = c(1.8, 1))

Code
# try bs = 20 for saving plots
if (!isTRUE(getOption("knitr.in.progress"))) {
    cowplot::ggsave2(filename = file.path(output_path, "violin_graphs_and_estimates_physiology_70dpi.jpeg"),
        width = 23, height = 9, device = grDevices::png)

    cowplot::ggsave2(filename = file.path(output_path, "violin_graphs_and_estimates_physiology_300dpi.jpeg"),
        dpi = 300, width = 23, height = 9, device = grDevices::png)
}

Violin plots, mean and SE on raw data

Code
# read INBREStressMeasuresRaw_5Dec25.csv

stress_raw <- read.csv(file.path(raw_data_path, "INBREStressMeasuresRaw_5Dec25.csv"))

stress_raw$week <- factor(stress_raw$Day,
                      levels = c(3, 7, 14, 21, 28),
                      labels = c("D3", "D7", "D14", "D21", "D28"))

stress_raw <- stress_raw[!is.na(stress_raw$BR), ]

stress_raw <- stress_raw[stress_raw$week != "D28", ]

stress_raw$day <- as.numeric(gsub("D", "", as.character(stress_raw$week)))
stress_raw$round <- paste("Round", stress_raw$Round)

stress_raw$Treatment <- gsub("Medium", "Med.", stress_raw$Treatment)

stress_raw$treatment <- factor(stress_raw$Treatment,
                           levels = c("Control", "Med. Stress", "High Stress"))

stress_raw$Week <- as.character(as.numeric(stress_raw$week))

agg_stress_raw <- aggregate(
    cbind(BR, Weight, CORT.Stress, CORT.Baseline) ~ Week + treatment,
    stress_raw,
    mean
)
agg_stress_raw_se <- aggregate(
     cbind(BR, Weight, CORT.Stress, CORT.Baseline)~ Week + treatment,
    stress_raw,
    standard_error
)

names(agg_stress_raw_se) <- paste(names(agg_stress_raw_se), ".se", sep = "")

agg_stress_raw <- cbind(agg_stress_raw, agg_stress_raw_se[, 3:6])



gg_breath.count <- ggplot(data = stress_raw, aes(x = Week, y = BR, fill = treatment)) +
    geom_violin(scale = "width") +
    geom_point(position = position_jitter(width = 0.1), alpha = 0.5, size = 1) +         
        scale_fill_viridis_d(begin = 0.1, end = 0.9, alpha = 0.9) +
    facet_wrap( ~ treatment, ncol = 3, scale = "fixed") +
    labs(y = "Breath rate (breaths/min)", x = "Week") +
    theme_classic(base_size = bs) +
    theme(legend.position = "none") +
          geom_errorbar(data = agg_stress_raw, aes(x = Week, y = BR,
            ymin = BR - BR.se,
            ymax = BR + BR.se
        ),
        width = 0, color = "white", size = 1.5
    ) + geom_point(data = agg_stress_raw, aes(x = Week, y = BR), fill = "white", size = 3, pch = 21)


gg_weight <- ggplot(data = stress_raw, aes(x = Week, y = Weight, fill = treatment)) +
    geom_violin(scale = "width") +
    geom_point(position = position_jitter(width = 0.1), alpha = 0.5, size = 1) +         
        scale_fill_viridis_d(begin = 0.1, end = 0.9, alpha = 0.9) +
    facet_wrap( ~ treatment, ncol = 3, scale = "fixed") +
    labs(y = "Weight (g)", x = "Week") +
    theme_classic(base_size = bs) +
    theme(legend.position = "none") +
          geom_errorbar(data = agg_stress_raw, aes(x = Week, y = Weight,
        
            ymin = Weight - Weight.se,
            ymax = Weight + Weight.se
        ),
        width = 0, color = "white", size = 1.5
    ) +
            geom_point(data = agg_stress_raw, aes(x = Week, y = Weight, fill = treatment), fill = "white", size = 3, pch = 21)


gg_cort.baseline <- 
    ggplot(data = stress_raw, aes(x = Week, y = CORT.Baseline, fill = treatment)) +
    geom_violin(scale = "width") +
    geom_point(position = position_jitter(width = 0.1), alpha = 0.5, size = 1) +         
        scale_fill_viridis_d(begin = 0.1, end = 0.9, alpha = 0.9) +
    facet_wrap( ~ treatment, ncol = 3, scale = "fixed") +
    labs(y = "Baseline CORT (ng/mL)", x = "Week") +
    theme_classic(base_size = bs) +
    theme(legend.position = "none") +
          geom_errorbar(data = agg_stress_raw, aes(x = Week, y = CORT.Baseline,
        
            ymin = CORT.Baseline - CORT.Baseline.se,
            ymax = CORT.Baseline + CORT.Baseline.se
        ),
        width = 0, color = "white", size = 1.5
    ) +
            geom_point(data = agg_stress_raw, aes(x = Week, y = CORT.Baseline, fill = treatment), fill = "white", size = 3, pch = 21)

gg_stress.response <-
    ggplot(data = stress_raw, aes(x = Week, y = CORT.Stress, fill = treatment)) +
    geom_violin(scale = "width") +
    geom_point(position = position_jitter(width = 0.1), alpha = 0.5, size = 1) +         
        scale_fill_viridis_d(begin = 0.1, end = 0.9, alpha = 0.9) +
    facet_wrap( ~ treatment, ncol = 3, scale = "fixed") +
    labs(y = "Stress response CORT (ng/mL)", x = "Week") +
    theme_classic(base_size = bs) +
    theme(legend.position = "none") +
          geom_errorbar(data = agg_stress_raw, aes(x = Week, y = CORT.Stress,
        
            ymin = CORT.Stress - CORT.Stress.se,
            ymax = CORT.Stress + CORT.Stress.se
        ),
        width = 0, color = "white", size = 1.5
    ) +
            geom_point(data = agg_stress_raw, aes(x = Week, y = CORT.Stress, fill = treatment), fill = "white", size = 3, pch = 21)

cowplot::plot_grid(
    gg_breath.count,
    gg_weight,
    gg_cort.baseline,
    gg_stress.response,
   nrow = 1,
    rel_heights = c(1.8, 1)
)

Code
# try bs = 20 for saving plots
if (!isTRUE(getOption('knitr.in.progress'))) {
    cowplot::ggsave2(
        filename = file.path(output_path, "violin_graphs_raw_physiology_70dpi.jpeg"),
        width = 23,
        height = 5,
        device = grDevices::png
    )
    
    cowplot::ggsave2(
        filename = file.path(output_path, "violin_graphs_raw_physiology_300dpi.jpeg"),
        dpi = 300,
        width = 23,
        height = 5,
        device = grDevices::png
    )
}

2.8 Takeaways

  • Breath rate decreases gradually across time after the first week

  • Stress response is higher in “high stress” birds compared to first week

 

3 Acoustic data

Colinearity of acoustic features

Code
feats <- sels[, c("duration", "meanfreq", "sd", "freq.median", "freq.IQR",
    "time.IQR", "skew", "kurt", "sp.ent", "time.ent", "entropy", "meandom",
    "mindom", "maxdom", "dfrange", "modindx", "meanpeakf")]

names(feats) <- c("Duration", "Mean frequency", "SD frequency", "Median Frequency",
    "IQR frequency", "IQR time", "Skewness", "Kurtosis", "Spetral entropy",
    "Time entropy", "Overall entropy", "Mean dominant", "Minimum dominant",
    "Maximum dominant", "Dominant range", "Modulation index", "Peak frequency")

cm <- cor(feats, use = "pairwise.complete.obs")

corrplot.mixed(cm, sig.level = 0.05, insig = "pch", pch.col = "gray",
    pch.cex = 0.9, upper = "ellipse", lower = "number", tl.col = "black",
    tl.pos = "lt", number.cex = 0.5, tl.cex = 0.7, mar = c(1, 1, 1,
        1), upper.col = colorrange, lower.col = colorrange2, order = "hclust")

Code
if (!isTRUE(getOption("knitr.in.progress"))) {
    dev.copy(png, file.path(output_path, "acoustic_features_colinearity.png"),
        width = 1700, height = 1500, res = 300)
    dev.off()  # Close the graphics device
}

3.1 Acoustic space projection

t-SNE

Code
tsne_acou_space <- read.csv(file.path(processed_data_path, "tsne_acoustic_space.csv"))

ids <- c("371YYLM", "395WBHM")

mat <- matrix(c(11:14, 1:4, 5:8, 22, 9, 9, 18), ncol = 4, byrow = TRUE)

mat <- cbind(c(23, 10, 10, 20), mat, c(21, 15, 16, 19))

mat <- rbind(rep(17, 6), mat)


if (!isTRUE(getOption("knitr.in.progress"))) jpeg(file.path(output_path,
    "acoustic_space_plot.jpg"), width = 1800, height = 2200, res = 300)

layout(mat, widths = c(0.4, 1, 1, 1, 1, 0.2), heights = c(4, 0.2,
    1, 1, 0.4))

par(mar = c(0, 0, 0, 0))
panel_count <- 1

colors <- viridis(3, alpha = 0.8)

for (x in ids) for (i in 1:4) {
    plot_space(X = tsne_acou_space, dimensions = c("TSNE1", "TSNE2"),
        indices = which(tsne_acou_space$ID == x & tsne_acou_space$week ==
            i), basecex = 2, pch = 20, labels = c(x, "group"), legend = NULL,
        xaxt = if (panel_count %in% mat[4, ])
            "s" else "n", yaxt = "n", colors = colors[1:2], point.cex = 1.7,
        point.alpha = 0.3, point.colors = c("black", "black"))

    # add y axis removing the upper tick label
    if (panel_count %in% mat[, 2])
        axis(2, at = seq(-60, 60, 20), labels = c(seq(-60, 40, 20),
            ""), tck = -0.02, lwd = 0.5, col = "black", col.axis = "black")

    panel_count <- panel_count + 1
}

par(mar = c(0, 0, 0, 0))

plot(1, frame.plot = FALSE, type = "n", yaxt = "n", xaxt = "n")

text(x = 1, y = 0.75, "TSNE1", cex = 1.2)

par(mar = c(0, 0, 0, 0))

plot(1, frame.plot = FALSE, type = "n", yaxt = "n", xaxt = "n")

text(x = 0.8, y = 1, "TSNE2", srt = 90, cex = 1.2)

for (u in paste("Week", 1:4)) {
    par(mar = c(0, 0, 0, 0))

    plot(1, frame.plot = FALSE, type = "n", yaxt = "n", xaxt = "n")

    if (u == "Week 1") {
        mtext("b", side = 2, line = 2.2, at = 1, las = 1, cex = 1.5)
    }

    rect(0, 0, 2, 2, col = colors[2], border = NA)

    box()
    text(x = 1, y = 1, u, cex = 1.2)
}

for (u in ids) {
    par(mar = c(0, 0, 0, 0))

    plot(1, frame.plot = FALSE, type = "n", yaxt = "n", xaxt = "n")
    rect(0, 0, 2, 2, col = colors[2], border = NA)

    box()

    text(x = 1, y = 1, u, srt = 270, cex = 1.2)
}

# set par to default
par(mar = c(2, 4, 1, 2) + 0.1)

# make scatter plot like gg_acou_space using base R plotting
# functions
plot(tsne_acou_space$TSNE1, tsne_acou_space$TSNE2, col = "white",
    pch = 20, cex = 1.2, xlab = "", ylab = "TSNE2", cex.lab = 1.2)

# add legend with no margin color
legend(x = -75, y = -25, legend = c("Control", "Medium Stress", "High Stress"),
    col = viridis::viridis(3, alpha = 0.3, direction = 1), pch = 20,
    box.lwd = 0, pt.cex = 1.8, cex = 1.2)

points(tsne_acou_space$TSNE1, tsne_acou_space$TSNE2, col = viridis::viridis(3,
    alpha = 0.3, direction = 1)[as.numeric(as.factor(tsne_acou_space$treatment))],
    pch = 20, cex = 1.2)

mtext("a", side = 2, line = 2.7, at = 65, las = 1, cex = 1.5)

if (!isTRUE(getOption("knitr.in.progress"))) dev.off()

3.2 Overlap between treatments

Code
ss <- space_similarity(treatment ~ TSNE1 + TSNE2, data = tsne_acou_space,
    method = "density.overlap")

print_kable(ss)
group.1 group.2 overlap.1in2 overlap.2in1 mean.overlap
1 Control High Stress 1.0000 0.8080 0.9040
2 Control Medium Stress 1.0000 0.8456 0.9228
3 High Stress Medium Stress 0.9354 1.0000 0.9677
  • Mean overlap: 0.9314969

  • Range of overlap: 0.9039941 to 0.9677128

3.3 Stats

Model: Predicted behavior ~ treatment + week (continuous) + IndRandom

Variables: # calls, Distance moved from self in first week, Overlap to original acoustic space, Match to group repertoire, Maybe overall size of acoustic space

Do as comparison to week one using rarefacted calls and kernel density

Code
responses <- c("call.count",
               "acoustic.diversity",
               "acustic.plasticity",
               "acoustic.convergence")

predictors <- c("~ treatment + week + (1|ID) + (1|round)")

formulas <- expand.grid(
    responses = responses,
    predictors = predictors,
    stringsAsFactors = FALSE
)

# vars_to_scale <- c(responses, "week")


# for (i in vars_to_scale) agg_dat[, vars_to_scale] <- scale(agg_dat[, vars_to_scale])

behav_models <- lapply(1:nrow(formulas), function(x) {
    sub_dat <- agg_dat[!is.na(agg_dat[names(agg_dat) == formulas$responses[x]]), ]
    
    # remove week 1
    if (!grepl("count|group", formulas$responses[x]))
        sub_dat <- sub_dat[sub_dat$week != 1, ]
    
    mod_name <- paste(formulas$responses[x],
                      gsub("~", "by", formulas$predictors[x]))
    
    
    mod <- brm(
        formula = paste(formulas$responses[x], formulas$predictors[x]),
        iter = 100000,
        family = if (formulas$responses[x] == "call.count")
            negbinomial() else
            Beta(link = "logit"),
        silent = 2,
        data = sub_dat,
        control = list(adapt_delta = 0.9, max_treedepth = 15),
        chains = 4,
        cores = 4,
        file = paste0(processed_data_path, "regressions/behav-", mod_name),
        file_refit = "always",
        prior = c(prior(normal(0, 5), "b"), prior(normal(0, 10), "Intercept") #,
                  # prior(student_t(3, 0, 10), "sd"),
                  # prior(student_t(3, 0, 10), "sigma"))
        )
        
        return(NULL)
})
Code
behav_models <- list.files(file.path(processed_data_path, "regressions"),
    pattern = "behav-", full.names = TRUE)

for (x in 1:length(behav_models)) extended_summary(read.file = behav_models[x],
    gsub.pattern = "b_treatment|b_", gsub.replacement = "", highlight = TRUE,
    remove.intercepts = TRUE)

3.4 behav-acoustic.convergence by treatment + week + (1|ID) + (1|round)

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 acoustic.convergence ~ treatment + week + (1 | ID) + (1 | round) beta (logit) b-normal(0, 5) Intercept-normal(0, 10) phi-gamma(0.01, 0.01) sd-student_t(3, 0, 2.5) 1e+05 4 1 50000 2682 (0.013%) 0 11010.11 24870.45 1543370143
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
HighStress 0.284 -0.380 0.970 1.001 11010.11 24870.45
MediumStress 0.328 -0.334 1.016 1.001 22753.15 53261.45
week -0.316 -0.564 -0.063 1 24236.72 33083.95

3.5 behav-acoustic.diversity by treatment + week + (1|ID) + (1|round)

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 acoustic.diversity ~ treatment + week + (1 | ID) + (1 | round) beta (logit) b-normal(0, 5) Intercept-normal(0, 10) phi-gamma(0.01, 0.01) sd-student_t(3, 0, 2.5) 1e+05 4 1 50000 6528 (0.033%) 0 20296.19 34793.85 195705932
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
HighStress -0.132 -0.730 0.461 1 20296.19 35122.53
MediumStress -0.558 -1.160 0.049 1 22357.72 45182.51
week 0.043 -0.107 0.188 1 35567.91 34793.85

3.6 behav-acustic.plasticity by treatment + week + (1|ID) + (1|round)

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 acustic.plasticity ~ treatment + week + (1 | ID) + (1 | round) beta (logit) b-normal(0, 5) Intercept-normal(0, 10) phi-gamma(0.01, 0.01) sd-student_t(3, 0, 2.5) 1e+05 4 1 50000 4613 (0.023%) 0 9587.206 25616.83 443607903
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
HighStress -1.068 -2.065 -0.065 1.001 9587.206 31322.73
MediumStress -0.245 -1.315 0.840 1 24675.909 56131.47
week 0.202 0.045 0.361 1 18446.592 25616.83

3.7 behav-call.count by treatment + week + (1|ID) + (1|round)

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 call.count ~ treatment + week + (1 | ID) + (1 | round) negbinomial (log) b-normal(0, 5) Intercept-normal(0, 10) sd-student_t(3, 0, 2.5) shape-inv_gamma(0.4, 0.3) 1e+05 4 1 50000 3227 (0.016%) 0 4923.233 1834.92 498436169
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
HighStress 1.341 0.325 2.351 1 31246.848 8083.761
MediumStress 0.872 -0.144 1.893 1 55318.238 75546.858
week -0.220 -0.440 -0.004 1.002 4923.233 1834.920

Code
behav_model_list <- list.files(file.path(processed_data_path, "regressions"),
    pattern = "behav-", full.names = TRUE)

# read all physio models
behav_models <- lapply(behav_model_list, readRDS)
names(behav_models) <- gsub(".rds", "", basename(behav_model_list))


agg_call.count <- aggregate(cbind(call.count, acoustic.convergence) ~
    week + treatment, agg_dat, mean)

agg_behav <- aggregate(cbind(acoustic.diversity, acustic.plasticity) ~
    week + treatment, agg_dat, mean)

agg_call.count_se <- aggregate(cbind(call.count, acoustic.convergence) ~
    week + treatment, agg_dat, standard_error)

agg_behav_se <- aggregate(cbind(acoustic.diversity, acustic.plasticity) ~
    week + treatment, agg_dat, standard_error)

agg_behav_se <- merge(agg_call.count_se, agg_behav_se, all = TRUE)

names(agg_behav_se) <- paste(names(agg_behav_se), ".se", sep = "")

agg_behav <- merge(agg_call.count, agg_behav, all = TRUE)

agg_behav <- cbind(agg_behav, agg_behav_se[, 3:6])

agg_behav$treatment <- gsub("Medium", "Med.", agg_behav$treatment)

agg_behav$treatment <- factor(agg_behav$treatment, levels = c("Control",
    "Med. Stress", "High Stress"))


gg_coeffs_behav <- lapply(behav_models, function(x) {
    vars <- grep("b_", posterior::variables(x), value = TRUE)
    draws <- posterior::as_draws_array(x, variable = vars)

    coef_table <- brmsish:::draw_summary(draws, variables = vars,
        probs = c(0.025, 0.975), robust = TRUE, spread.type = "HPDI")

    coef_table$predictor <- rownames(coef_table)
    coef_table$predictor <- gsub("b_treatment|b_", "", coef_table$predictor)
    coef_table$predictor <- gsub("Stress", " stress", coef_table$predictor)
    coef_table$predictor <- gsub("week", "Week", coef_table$predictor)
    coef_table <- coef_table[coef_table$predictor != "Intercept",
        ]

    gg_coef <- ggplot2::ggplot(data = coef_table, aes(x = Estimate,
        y = predictor)) + geom_vline(xintercept = 0, lty = 2) + ggplot2::geom_point(size = 4,
        col = col_pointrange) + ggplot2::geom_errorbar(ggplot2::aes(xmin = `l-95% CI`,
        xmax = `u-95% CI`), width = 0, col = col_pointrange) + ggplot2::theme_classic(base_size = bs) +
        ggplot2::theme(axis.ticks.length = ggplot2::unit(0, "pt"),
            plot.margin = ggplot2::margin(0, 0, 0, 0, "pt"), legend.position = "none",
            strip.background = ggplot2::element_blank(), strip.text = ggplot2::element_blank()) +
        ggplot2::labs(x = "Effect size", y = "")

    return(gg_coef)
})



cowplot::plot_grid(gg_call.count, gg_acoustic.diversity, gg_acustic.plasticity,
    gg_acoustic.convergence, gg_coeffs_behav[[grep("count", names(gg_coeffs_behav))]] +
        theme_classic(base_size = bs), gg_coeffs_behav[[grep("diversity",
        names(gg_coeffs_behav))]] + theme_classic(base_size = bs),
    gg_coeffs_behav[[grep("plasticity", names(gg_coeffs_behav))]] +
        theme_classic(base_size = bs), gg_coeffs_behav[[grep("convergence",
        names(gg_coeffs_behav))]] + theme_classic(base_size = bs),
    nrow = 2, rel_heights = c(1.8, 1))

# try bs = 20 for saving plots

if (!isTRUE(getOption("knitr.in.progress"))) {
    cowplot::ggsave2(filename = file.path(output_path, "bar_graphs_and_estimates_behavior_70dpi.jpeg"),
        width = 23, height = 9, device = grDevices::png)
    #
    cowplot::ggsave2(filename = file.path(output_path, "bar_graphs_and_estimates_behavior_300dpi.jpeg"),
        dpi = 300, width = 23, height = 9, device = grDevices::png)
}

Violin plots and effect sizes graph

Code
behav_model_list <- list.files(file.path(processed_data_path, "regressions"),
    pattern = "behav-", full.names = TRUE)

# read all physio models
behav_models <- lapply(behav_model_list, readRDS)
names(behav_models) <- gsub(".rds", "", basename(behav_model_list))


agg_call.count <- aggregate(cbind(call.count, acoustic.convergence) ~
    week + treatment, agg_dat, mean)

agg_behav <- aggregate(cbind(acoustic.diversity, acustic.plasticity) ~
    week + treatment, agg_dat, mean)

agg_call.count_se <- aggregate(cbind(call.count, acoustic.convergence) ~
    week + treatment, agg_dat, standard_error)

agg_behav_se <- aggregate(cbind(acoustic.diversity, acustic.plasticity) ~
    week + treatment, agg_dat, standard_error)

agg_behav_se <- merge(agg_call.count_se, agg_behav_se, all = TRUE)

names(agg_behav_se) <- paste(names(agg_behav_se), ".se", sep = "")

agg_behav <- merge(agg_call.count, agg_behav, all = TRUE)

agg_behav <- cbind(agg_behav, agg_behav_se[, 3:6])


agg_dat$treatment <- gsub("Medium", "Med.", agg_dat$treatment)

agg_dat$treatment <- factor(agg_dat$treatment, levels = c("Control",
    "Med. Stress", "High Stress"))

agg_behav$treatment <- gsub("Medium", "Med.", agg_behav$treatment)

agg_behav$treatment <- factor(agg_behav$treatment, levels = c("Control",
    "Med. Stress", "High Stress"))


gg_call.count <- ggplot(data = agg_dat, aes(x = as.factor(week), y = call.count,
    fill = treatment)) + geom_violin(scale = "width") + geom_point(position = position_jitter(width = 0.1),
    alpha = 0.5, size = 1) + scale_fill_viridis_d(begin = 0.1, end = 0.9,
    alpha = 0.9) + facet_wrap(~treatment, ncol = 3, scale = "fixed") +
    labs(y = "Vocal output", x = "Week") + theme_classic(base_size = bs) +
    theme(legend.position = "none") + geom_errorbar(data = agg_behav,
    aes(x = week, y = call.count, ymin = call.count - call.count.se,
        ymax = call.count + call.count.se), width = 0, color = "white",
    size = 1.5) + geom_point(data = agg_behav, aes(x = as.factor(week),
    y = call.count), fill = "white", size = 3, pch = 21)


agg_dat$acoustic.diversity[agg_dat$week == 1] <- NA

gg_acoustic.diversity <- ggplot(data = agg_dat, aes(x = as.factor(week),
    y = acoustic.diversity, fill = treatment)) + geom_violin(scale = "width") +
    geom_point(position = position_jitter(width = 0.1), alpha = 0.5,
        size = 1) + scale_fill_viridis_d(begin = 0.1, end = 0.9, alpha = 0.9) +
    facet_wrap(~treatment, ncol = 3, scale = "fixed") + labs(y = "Change in vocal diversity",
    x = "Week") + theme_classic(base_size = bs) + theme(legend.position = "none") +
    geom_errorbar(data = agg_behav, aes(x = week, y = acoustic.diversity,
        ymin = acoustic.diversity - acoustic.diversity.se, ymax = acoustic.diversity +
            acoustic.diversity.se), width = 0, color = "white", size = 1.5) +
    geom_point(data = agg_behav, aes(x = as.factor(week), y = acoustic.diversity),
        fill = "white", size = 3, pch = 21)

agg_dat$acustic.plasticity[agg_dat$week == 1] <- NA

gg_acustic.plasticity <- ggplot(data = agg_dat, aes(x = as.factor(week),
    y = acustic.plasticity, fill = treatment)) + geom_violin(scale = "width") +
    geom_point(position = position_jitter(width = 0.1), alpha = 0.5,
        size = 1) + scale_fill_viridis_d(begin = 0.1, end = 0.9, alpha = 0.9) +
    facet_wrap(~treatment, ncol = 3, scale = "fixed") + labs(y = "Vocal plasticity",
    x = "Week") + theme_classic(base_size = bs) + theme(legend.position = "none") +
    geom_errorbar(data = agg_behav, aes(x = week, y = acustic.plasticity,
        ymin = acustic.plasticity - acustic.plasticity.se, ymax = acustic.plasticity +
            acustic.plasticity.se), width = 0, color = "white", size = 1.5) +
    geom_point(data = agg_behav, aes(x = as.factor(week), y = acustic.plasticity),
        fill = "white", size = 3, pch = 21)


gg_acoustic.convergence <- ggplot(data = agg_dat, aes(x = as.factor(week),
    y = acoustic.convergence, fill = treatment)) + geom_violin(scale = "width") +
    geom_point(position = position_jitter(width = 0.1), alpha = 0.5,
        size = 1) + scale_fill_viridis_d(begin = 0.1, end = 0.9, alpha = 0.9) +
    facet_wrap(~treatment, ncol = 3, scale = "fixed") + labs(y = "Vocal convergence",
    x = "Week") + theme_classic(base_size = bs) + theme(legend.position = "none") +
    geom_errorbar(data = agg_behav, aes(x = week, y = acoustic.convergence,
        ymin = acoustic.convergence - acoustic.convergence.se, ymax = acoustic.convergence +
            acoustic.convergence.se), width = 0, color = "white",
        size = 1.5) + geom_point(data = agg_behav, aes(x = as.factor(week),
    y = acoustic.convergence), fill = "white", size = 3, pch = 21)


gg_coeffs_behav <- lapply(behav_models, function(x) {
    vars <- grep("b_", posterior::variables(x), value = TRUE)
    draws <- posterior::as_draws_array(x, variable = vars)

    coef_table <- brmsish:::draw_summary(draws, variables = vars,
        probs = c(0.025, 0.975), robust = TRUE, spread.type = "HPDI")

    coef_table$predictor <- rownames(coef_table)
    coef_table$predictor <- gsub("b_treatment|b_", "", coef_table$predictor)
    coef_table$predictor <- gsub("Stress", " stress", coef_table$predictor)
    coef_table$predictor <- gsub("Medium", "Med.", coef_table$predictor)
    coef_table$predictor <- gsub("week", "Week", coef_table$predictor)
    coef_table <- coef_table[coef_table$predictor != "Intercept",
        ]

    gg_coef <- ggplot2::ggplot(data = coef_table, aes(x = Estimate,
        y = predictor)) + geom_vline(xintercept = 0, lty = 2) + ggplot2::geom_point(size = 4,
        col = col_pointrange) + ggplot2::geom_errorbar(ggplot2::aes(xmin = `l-95% CI`,
        xmax = `u-95% CI`), width = 0, col = col_pointrange) + ggplot2::theme_classic(base_size = bs) +
        ggplot2::theme(axis.ticks.length = ggplot2::unit(0, "pt"),
            plot.margin = ggplot2::margin(0, 0, 0, 0, "pt"), legend.position = "none",
            strip.background = ggplot2::element_blank(), strip.text = ggplot2::element_blank()) +
        ggplot2::labs(x = "Effect size", y = "")

    return(gg_coef)
})



cowplot::plot_grid(gg_call.count, gg_acoustic.diversity, gg_acustic.plasticity,
    gg_acoustic.convergence, gg_coeffs_behav[[grep("count", names(gg_coeffs_behav))]] +
        theme_classic(base_size = bs), gg_coeffs_behav[[grep("diversity",
        names(gg_coeffs_behav))]] + theme_classic(base_size = bs),
    gg_coeffs_behav[[grep("plasticity", names(gg_coeffs_behav))]] +
        theme_classic(base_size = bs), gg_coeffs_behav[[grep("convergence",
        names(gg_coeffs_behav))]] + theme_classic(base_size = bs),
    nrow = 2, rel_heights = c(1.8, 1))

Code
# try bs = 20 for saving plots

if (!isTRUE(getOption("knitr.in.progress"))) {
    cowplot::ggsave2(filename = file.path(output_path, "violin_graphs_and_estimates_behavior_70dpi.jpeg"),
        width = 23, height = 9, device = grDevices::png)
    #
    cowplot::ggsave2(filename = file.path(output_path, "violin_graphs_and_estimates_behavior_300dpi.jpeg"),
        dpi = 300, width = 23, height = 9, device = grDevices::png)
}

3.8 Takeaways

  • Lower vocal output over time

  • Higher vocal output in “high stress” birds compared to control

  • Lower acoustic plasticity to themselves in week 1 for “high stress” birds compared to control

  • Increase in acoustic plasticity over time

 

4 FOXP2

4.1 FoxP2 positive cells in MMST:VSP

4.1.1 Stats

Code
foxp2_mod <- brm(formula = FoxP2.Counts.MMSt.Striatum ~ Treatment,
    iter = 1e+05, family = Gamma(link = "log"), silent = 2, data = foxp2,
    control = list(adapt_delta = 0.9, max_treedepth = 15), chains = 4,
    cores = 4, file = file.path(processed_data_path, "regressions/foxp2_by_treatment_model"),
    file_refit = "on_change", prior = c(prior(normal(0, 5), "b"),
        prior(normal(0, 10), "Intercept")))
Code
extended_summary(read.file = file.path(processed_data_path, "regressions/foxp2_by_treatment_model.rds"),
    gsub.pattern = "b_treatment|b_", gsub.replacement = "", highlight = TRUE,
    remove.intercepts = TRUE)

4.2 foxp2_by_treatment_model

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 FoxP2.Counts.MMSt.Striatum ~ Treatment gamma (log) b-normal(0, 5) Intercept-normal(0, 10) shape-gamma(0.01, 0.01) 1e+05 4 1 50000 0 (0%) 0 145217.7 129358 411186403
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
TreatmentMediumstress -0.013 -0.284 0.257 1 150039.8 129358.0
TreatmentHighstress 0.071 -0.198 0.342 1 145217.7 132119.9

4.3 FoxP2 mRNA expression MMST:VSP

Code
qpcr <- read.csv(file.path(raw_data_path, "qpcr_foxp2_expression.csv"))

4.3.1 Stats

Code
mod <- brm(formula = FoxP2.mRNA.MMST.VSP ~ Treatment, iter = 1e+05,
    family = Gamma(link = "log"), silent = 2, data = qpcr, control = list(adapt_delta = 0.9,
        max_treedepth = 15), chains = 4, cores = 4, file = file.path(processed_data_path,
        "regressions/qpcr_by_treatment_model"), file_refit = "on_change",
    prior = c(prior(normal(0, 5), "b"), prior(normal(0, 10), "Intercept")))
Code
extended_summary(read.file = file.path(processed_data_path, "regressions/qpcr_by_treatment_model.rds"),
    gsub.pattern = "b_treatment|b_", gsub.replacement = "", highlight = TRUE,
    remove.intercepts = TRUE)

4.4 qpcr_by_treatment_model

formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 FoxP2.mRNA.MMST.VSP ~ Treatment gamma (log) b-normal(0, 5) Intercept-normal(0, 10) shape-gamma(0.01, 0.01) 1e+05 4 1 50000 0 (0%) 0 96059.45 95166.01 1953559397
Estimate l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
TreatmentHighStress 0.438 -0.303 1.158 1 96059.45 95522.95
TreatmentMedium -0.171 -0.890 0.508 1 98207.68 95166.01

Barplot and effect sizes graph

Code
agg_foxp2 <- aggregate(FoxP2.Counts.MMSt.Striatum ~ Treatment, foxp2,
    mean)

agg_foxp2$se <- aggregate(FoxP2.Counts.MMSt.Striatum ~ Treatment,
    foxp2, standard_error)$FoxP2.Counts.MMSt.Striatum


gg_foxp2 <- ggplot(data = foxp2, aes(x = Treatment, y = FoxP2.Counts.MMSt.Striatum,
    fill = Treatment)) + geom_violin(scale = "width") + geom_point(position = position_jitter(width = 0.1),
    alpha = 0.5, size = 1) + scale_x_discrete(labels = c(Control = "Control",
    `Medium stress` = "Med. stress", `High stress` = "High stress")) +
    scale_fill_viridis_d(begin = 0.1, end = 0.9, alpha = 0.7) + labs(y = "FoxP2 positive\ncells in MMSt:VSP",
    x = "Treatment") + theme_classic(base_size = bs) + theme_classic(base_size = bs) +
    theme(legend.position = "none") + geom_errorbar(data = agg_foxp2,
    aes(x = Treatment, y = FoxP2.Counts.MMSt.Striatum, ymin = FoxP2.Counts.MMSt.Striatum -
        se, ymax = FoxP2.Counts.MMSt.Striatum + se), width = 0, color = "white",
    size = 1.5) + geom_point(data = agg_foxp2, aes(x = Treatment,
    y = FoxP2.Counts.MMSt.Striatum), fill = "white", size = 3, pch = 21)



agg_mrna <- aggregate(FoxP2.mRNA.MMST.VSP ~ Treatment, qpcr, mean)

agg_mrna$se <- aggregate(FoxP2.mRNA.MMST.VSP ~ Treatment, qpcr, standard_error)$FoxP2.mRNA.MMST.VSP

# order levels
agg_foxp2$Treatment <- factor(agg_foxp2$Treatment, levels = c("Control",
    "Medium stress", "High stress"))
agg_mrna$Treatment <- factor(agg_mrna$Treatment, levels = c("Control",
    "Medium", "High Stress"))


gg_qpcr <- ggplot(data = qpcr, aes(x = Treatment, y = FoxP2.mRNA.MMST.VSP,
    fill = Treatment)) + geom_violin(scale = "width") + geom_point(position = position_jitter(width = 0.1),
    alpha = 0.5, size = 1) + scale_x_discrete(labels = c(Control = "Control",
    Medium = "Med. stress", `High Stress` = "High stress")) + scale_fill_viridis_d(begin = 0.1,
    end = 0.9, alpha = 0.7) + labs(y = "FoxP2 mRNA\nexpression MMSt:VSP",
    x = "Treatment") + theme_classic(base_size = bs) + theme_classic(base_size = bs) +
    theme(legend.position = "none") + geom_errorbar(data = agg_mrna,
    aes(x = Treatment, y = FoxP2.mRNA.MMST.VSP, ymin = FoxP2.mRNA.MMST.VSP -
        se, ymax = FoxP2.mRNA.MMST.VSP + se), width = 0, color = "white",
    size = 1.5) + geom_point(data = agg_mrna, aes(x = Treatment, y = FoxP2.mRNA.MMST.VSP),
    fill = "white", size = 3, pch = 21)

foxp2_cells_mod <- readRDS(file.path(processed_data_path, "regressions/foxp2_by_treatment_model.rds"))
qpcr_mod <- readRDS(file.path(processed_data_path, "regressions/qpcr_by_treatment_model.rds"))

gg_coeffs_foxp2 <- lapply(list(foxp2_cells_mod, qpcr_mod), function(x) {
    vars <- grep("b_", posterior::variables(x), value = TRUE)
    draws <- posterior::as_draws_array(x, variable = vars)

    coef_table <- brmsish:::draw_summary(draws, variables = vars,
        probs = c(0.025, 0.975), robust = TRUE, spread.type = "HPDI")

    coef_table$predictor <- rownames(coef_table)
    coef_table$predictor <- gsub("b_treatment|b_", "", coef_table$predictor)
    coef_table$predictor <- gsub("Stress", " stress", coef_table$predictor)
    coef_table$predictor <- gsub("week", "Week", coef_table$predictor)
    coef_table$predictor <- gsub("Treatment", "", coef_table$predictor)
    coef_table$predictor <- gsub("Mediumstress|Medium", "Med. stress",
        coef_table$predictor)
    coef_table$predictor <- gsub("Highstress", "High stress", coef_table$predictor)
    coef_table <- coef_table[coef_table$predictor != "Intercept",
        ]

    gg_coef <- ggplot2::ggplot(data = coef_table, aes(x = Estimate,
        y = predictor)) + geom_vline(xintercept = 0, lty = 2) + ggplot2::geom_point(size = 4,
        col = col_pointrange) + ggplot2::geom_errorbar(ggplot2::aes(xmin = `l-95% CI`,
        xmax = `u-95% CI`), width = 0, col = col_pointrange) + ggplot2::theme_classic(base_size = bs) +
        ggplot2::theme(axis.ticks.length = ggplot2::unit(0, "pt"),
            plot.margin = ggplot2::margin(0, 0, 0, 0, "pt"), legend.position = "none",
            strip.background = ggplot2::element_blank(), strip.text = ggplot2::element_blank()) +
        ggplot2::labs(x = "Effect size", y = "")

    return(gg_coef)
})

cowplot::plot_grid(gg_foxp2, gg_qpcr, gg_coeffs_foxp2[[1]] + theme_classic(base_size = bs),
    gg_coeffs_foxp2[[2]] + theme_classic(base_size = bs), nrow = 2,
    rel_heights = c(1.8, 1))

Code
# try bs = 20 for saving plots

cowplot::ggsave2(filename = file.path(output_path, "bar_graphs_and_estimates_foxp2_70dpi.jpeg"),
    width = 15, height = 10, device = grDevices::png)

cowplot::ggsave2(filename = file.path(output_path, "bar_graphs_and_estimates_foxp2_300dpi.jpeg"),
    dpi = 300, width = 15, height = 10, device = grDevices::png)

Raw values

Code
agg_foxp2_raw <- aggregate(X..FoxP2.Positive.Cells.MMST.MMST ~ Treatment,
    foxp2, mean)

agg_foxp2_raw$se <- aggregate(X..FoxP2.Positive.Cells.MMST.MMST ~
    Treatment, foxp2, standard_error)$X..FoxP2.Positive.Cells.MMST.MMST

foxp2$Treatment <- factor(foxp2$Treatment, levels = c("Control", "Medium stress",
    "High stress"))

gg_foxp2_raw <- ggplot(data = foxp2, aes(x = Treatment, y = X..FoxP2.Positive.Cells.MMST.MMST,
    fill = Treatment)) + geom_violin(scale = "width") + geom_point(position = position_jitter(width = 0.1),
    alpha = 0.5, size = 1) + scale_x_discrete(labels = c(Control = "Control",
    `Medium stress` = "Med. stress", `High stress` = "High stress")) +
    scale_fill_viridis_d(begin = 0.1, end = 0.9, alpha = 0.7) + labs(y = "FoxP2 positive\ncells in MMSt (%)",
    x = "Treatment") + theme_classic(base_size = bs) + theme_classic(base_size = bs) +
    theme(legend.position = "none") + geom_errorbar(data = agg_foxp2_raw,
    aes(x = Treatment, y = X..FoxP2.Positive.Cells.MMST.MMST, ymin = X..FoxP2.Positive.Cells.MMST.MMST -
        se, ymax = X..FoxP2.Positive.Cells.MMST.MMST + se), width = 0,
    color = "white", size = 1.5) + geom_point(data = agg_foxp2_raw,
    aes(x = Treatment, y = X..FoxP2.Positive.Cells.MMST.MMST), fill = "white",
    size = 3, pch = 21)


foxp2_raw <- read.csv(file.path(raw_data_path, "INBREmale_qPCR_FINAL_5Dec25.csv"))

agg_mrna_raw <- aggregate(FoxP2.2.ddCt.MMSt ~ Treatment, foxp2_raw,
    mean)

agg_mrna_raw$se <- aggregate(FoxP2.2.ddCt.MMSt ~ Treatment, foxp2_raw,
    standard_error)$FoxP2.2.ddCt.MMSt

foxp2_raw$Treatment <- factor(foxp2_raw$Treatment, levels = c("Control",
    "Medium", "High Stress"))

gg_mrna_raw <- ggplot(data = foxp2_raw, aes(x = Treatment, y = FoxP2.2.ddCt.MMSt,
    fill = Treatment)) + geom_violin(scale = "width") + geom_point(position = position_jitter(width = 0.1),
    alpha = 0.5, size = 1) + scale_x_discrete(labels = c(Control = "Control",
    Medium = "Med. stress", `High Stress` = "High stress")) + scale_fill_viridis_d(begin = 0.1,
    end = 0.9, alpha = 0.7) + labs(y = "FoxP2 mRNA\nexpression in MMSt",
    x = "Treatment") + theme_classic(base_size = bs) + theme_classic(base_size = bs) +
    theme(legend.position = "none") + geom_errorbar(data = agg_mrna_raw,
    aes(x = Treatment, y = FoxP2.2.ddCt.MMSt, ymin = FoxP2.2.ddCt.MMSt -
        se, ymax = FoxP2.2.ddCt.MMSt + se), width = 0, color = "white",
    size = 1.5) + geom_point(data = agg_mrna_raw, aes(x = Treatment,
    y = FoxP2.2.ddCt.MMSt), fill = "white", size = 3, pch = 21)


cowplot::plot_grid(gg_foxp2, gg_qpcr, gg_foxp2_raw, gg_mrna_raw, nrow = 2,
    rel_heights = c(1, 1))

Code
# try bs = 20 for saving plots
if (!isTRUE(getOption("knitr.in.progress"))) {
    cowplot::ggsave2(filename = file.path(output_path, "violin_plots_foxp2_70dpi.jpeg"),
        width = 15, height = 10, device = grDevices::png)

    cowplot::ggsave2(filename = file.path(output_path, "violin_plots_foxp2_300dpi.jpeg"),
        dpi = 300, width = 15, height = 10, device = grDevices::png)

    cowplot::plot_grid(gg_foxp2_raw + theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank(), axis.title.x = element_blank()),
        gg_mrna_raw + theme(axis.ticks.x = element_blank(), axis.text.x = element_blank(),
            axis.title.x = element_blank()), gg_foxp2, gg_qpcr, gg_coeffs_foxp2[[1]] +
            theme_classic(base_size = bs), gg_coeffs_foxp2[[2]] +
            theme_classic(base_size = bs), nrow = 3, rel_heights = c(1.4,
            1.8, 1))

    cowplot::ggsave2(filename = file.path(output_path, "violin_plots_and_estimates_foxp2_70dpi.jpeg"),
        width = 15, height = 10, device = grDevices::png)

    cowplot::ggsave2(filename = file.path(output_path, "violin_plots_and_estimates_foxp2_300dpi.jpeg"),
        dpi = 300, width = 15, height = 10, device = grDevices::png)
}

5 Combined model diagnostics

Code
check_rds_fits(path = file.path(processed_data_path, "regressions"),
    html = TRUE)
fit formula family priors iterations chains thinning warmup diverg_transitions rhats > 1.05 min_bulk_ESS min_tail_ESS seed
1 behav-acoustic.convergence by treatment + week + (1|ID) + (1|round).rds acoustic.convergence ~ treatment + week + (1 | ID) + (1 | round) beta (logit) b-normal(0, 5) Intercept-normal(0, 10) phi-gamma(0.01, 0.01) sd-student_t(3, 0, 2.5) 1e+05 4 1 50000 2682 (0.01341%) 0 1508 906 1543370143
2 behav-acoustic.diversity by treatment + week + (1|ID) + (1|round).rds acoustic.diversity ~ treatment + week + (1 | ID) + (1 | round) beta (logit) b-normal(0, 5) Intercept-normal(0, 10) phi-gamma(0.01, 0.01) sd-student_t(3, 0, 2.5) 1e+05 4 1 50000 6528 (0.03264%) 0 1419 644 195705932
3 behav-acustic.plasticity by treatment + week + (1|ID) + (1|round).rds acustic.plasticity ~ treatment + week + (1 | ID) + (1 | round) beta (logit) b-normal(0, 5) Intercept-normal(0, 10) phi-gamma(0.01, 0.01) sd-student_t(3, 0, 2.5) 1e+05 4 1 50000 4613 (0.023065%) 0 973 311 443607903
4 behav-call.count by treatment + week + (1|ID) + (1|round).rds call.count ~ treatment + week + (1 | ID) + (1 | round) negbinomial (log) b-normal(0, 5) Intercept-normal(0, 10) sd-student_t(3, 0, 2.5) shape-inv_gamma(0.4, 0.3) 1e+05 4 1 50000 3227 (0.016135%) 0 1720 764 498436169
5 foxp2_by_treatment_model.rds FoxP2.Counts.MMSt.Striatum ~ Treatment gamma (log) b-normal(0, 5) Intercept-normal(0, 10) shape-gamma(0.01, 0.01) 1e+05 4 1 50000 0 (0%) 0 77833 99167 411186403
6 physio-acustic.plasticity by treatment + week + (1|ID) + (1|round).rds breath.rate ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 0 (0%) 0 67534 63482 1702562168
7 physio-baseline.CORT by treatment + week + (1|ID) + (1|round).rds baseline.CORT ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 6255 (0.031275%) 0 1288 419 662141751
8 physio-breath.rate by treatment + week + (1|ID) + (1|round).rds breath.rate ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 5808 (0.02904%) 0 555 156 1411987597
9 physio-stress.CORT by treatment + week + (1|ID) + (1|round).rds stress.CORT ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 1796 (0.00898%) 0 6443 2528 1854922145
10 physio-stress.response by treatment + week + (1|ID) + (1|round).rds stress.response ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 4766 (0.02383%) 0 733 109 1337746393
11 physio-weight by treatment + week + (1|ID) + (1|round).rds weight ~ treatment + week + (1 | ID) + (1 | round) student (identity) b-normal(0, 5) Intercept-normal(0, 10) nu-gamma(2, 0.1) sd-student_t(3, 0, 10) sigma-student_t(3, 0, 10) 1e+05 4 1 50000 4876 (0.02438%) 0 708 223 1479872948
12 qpcr_by_treatment_model.rds FoxP2.mRNA.MMST.VSP ~ Treatment gamma (log) b-normal(0, 5) Intercept-normal(0, 10) shape-gamma(0.01, 0.01) 1e+05 4 1 50000 0 (0%) 0 66357 82682 1953559397

Session information

Click to see
─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.5.2 (2025-10-31)
 os       Ubuntu 22.04.5 LTS
 system   x86_64, linux-gnu
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       America/Costa_Rica
 date     2025-12-16
 pandoc   3.2 @ /usr/lib/rstudio/resources/app/bin/quarto/bin/tools/x86_64/ (via rmarkdown)
 quarto   1.7.31 @ /usr/local/bin/quarto

─ Packages ───────────────────────────────────────────────────────────────────
 package          * version  date (UTC) lib source
 abind              1.4-8    2024-09-12 [1] CRAN (R 4.5.0)
 ape                5.8-1    2024-12-16 [1] CRAN (R 4.5.0)
 arrayhelpers       1.1-0    2020-02-04 [1] CRAN (R 4.5.0)
 backports          1.5.0    2024-05-23 [1] CRAN (R 4.5.0)
 bayesplot          1.14.0   2025-08-31 [1] CRAN (R 4.5.0)
 boot               1.3-32   2025-08-29 [4] CRAN (R 4.5.1)
 bridgesampling     1.2-1    2025-11-19 [1] CRAN (R 4.5.0)
 brms             * 2.23.0   2025-09-09 [1] CRAN (R 4.5.0)
 brmsish          * 1.0.0    2025-12-08 [1] CRANs (R 4.5.0)
 Brobdingnag        1.2-9    2022-10-19 [1] CRAN (R 4.5.0)
 cachem             1.1.0    2024-05-16 [1] CRAN (R 4.5.0)
 cellranger         1.1.0    2016-07-27 [3] CRAN (R 4.0.1)
 checkmate          2.3.3    2025-08-18 [1] CRAN (R 4.5.0)
 class              7.3-23   2025-01-01 [4] CRAN (R 4.4.2)
 classInt           0.4-11   2025-01-08 [1] CRAN (R 4.5.0)
 cli                3.6.5    2025-04-23 [1] CRAN (R 4.5.0)
 cluster            2.1.8.1  2025-03-12 [4] CRAN (R 4.4.3)
 coda               0.19-4.1 2024-01-31 [1] CRAN (R 4.5.0)
 codetools          0.2-20   2024-03-31 [4] CRAN (R 4.5.0)
 corrplot         * 0.95     2024-10-14 [1] CRAN (R 4.5.0)
 cowplot          * 1.2.0    2025-07-07 [1] CRAN (R 4.5.0)
 crayon             1.5.3    2024-06-20 [1] CRAN (R 4.5.0)
 curl               7.0.0    2025-08-19 [1] CRAN (R 4.5.0)
 DBI                1.2.3    2024-06-02 [1] CRAN (R 4.5.0)
 deldir             2.0-4    2024-02-28 [1] CRAN (R 4.5.0)
 devtools           2.4.5    2022-10-11 [1] CRAN (R 4.5.0)
 digest             0.6.39   2025-11-19 [1] CRAN (R 4.5.0)
 distributional     0.5.0    2024-09-17 [1] CRAN (R 4.5.0)
 dplyr              1.1.4    2023-11-17 [1] CRAN (R 4.5.0)
 e1071              1.7-16   2024-09-16 [1] CRAN (R 4.5.0)
 ellipsis           0.3.2    2021-04-29 [3] CRAN (R 4.1.1)
 emmeans            1.11.1   2025-05-04 [3] CRAN (R 4.5.0)
 estimability       1.5.1    2024-05-12 [3] CRAN (R 4.5.0)
 evaluate           1.0.5    2025-08-27 [1] CRAN (R 4.5.0)
 farver             2.1.2    2024-05-13 [1] CRAN (R 4.5.0)
 fastmap            1.2.0    2024-05-15 [1] CRAN (R 4.5.0)
 formatR          * 1.14     2023-01-17 [1] CRAN (R 4.5.0)
 fs                 1.6.6    2025-04-12 [1] CRAN (R 4.5.0)
 generics           0.1.4    2025-05-09 [1] CRAN (R 4.5.0)
 ggdist             3.3.3    2025-04-23 [1] CRAN (R 4.5.0)
 ggplot2          * 4.0.1    2025-11-14 [1] CRAN (R 4.5.0)
 glue               1.8.0    2024-09-30 [1] CRAN (R 4.5.0)
 goftest            1.2-3    2021-10-07 [3] CRAN (R 4.1.1)
 gridExtra          2.3      2017-09-09 [1] CRAN (R 4.5.0)
 gtable             0.3.6    2024-10-25 [1] CRAN (R 4.5.0)
 htmltools          0.5.9    2025-12-04 [1] CRAN (R 4.5.0)
 htmlwidgets        1.6.4    2023-12-06 [1] RSPM (R 4.5.0)
 httpuv             1.6.16   2025-04-16 [1] RSPM (R 4.5.0)
 inline             0.3.21   2025-01-09 [1] CRAN (R 4.5.0)
 jsonlite           2.0.0    2025-03-27 [1] CRAN (R 4.5.0)
 kableExtra       * 1.4.0    2024-01-24 [1] CRAN (R 4.5.0)
 KernSmooth         2.23-26  2025-01-01 [4] CRAN (R 4.4.2)
 knitr            * 1.50     2025-03-16 [1] CRAN (R 4.5.0)
 labeling           0.4.3    2023-08-29 [1] CRAN (R 4.5.0)
 later              1.4.2    2025-04-08 [1] RSPM (R 4.5.0)
 lattice            0.22-7   2025-04-02 [4] CRAN (R 4.5.0)
 lifecycle          1.0.4    2023-11-07 [1] CRAN (R 4.5.0)
 lme4             * 1.1-37   2025-03-26 [1] CRAN (R 4.5.0)
 loo                2.8.0    2024-07-03 [1] CRAN (R 4.5.0)
 lubridate          1.9.4    2024-12-08 [3] CRAN (R 4.5.0)
 magrittr           2.0.4    2025-09-12 [1] CRAN (R 4.5.0)
 MASS             * 7.3-65   2025-02-28 [4] CRAN (R 4.4.3)
 Matrix           * 1.7-4    2025-08-28 [4] CRAN (R 4.5.1)
 matrixStats        1.5.0    2025-01-07 [1] CRAN (R 4.5.0)
 memoise            2.0.1    2021-11-26 [1] CRAN (R 4.5.0)
 mgcv               1.9-3    2025-04-04 [4] CRAN (R 4.5.0)
 mime               0.13     2025-03-17 [1] CRAN (R 4.5.0)
 miniUI             0.1.2    2025-04-17 [3] CRAN (R 4.5.0)
 minqa              1.2.4    2014-10-09 [3] CRAN (R 4.0.1)
 multcomp           1.4-28   2025-01-29 [3] CRAN (R 4.5.0)
 mvtnorm            1.3-3    2025-01-10 [1] CRAN (R 4.5.0)
 nicheROVER         1.1.2    2023-10-13 [1] CRAN (R 4.5.0)
 nlme               3.1-168  2025-03-31 [4] CRAN (R 4.4.3)
 nloptr             2.2.1    2025-03-17 [3] CRAN (R 4.5.0)
 packrat            0.7.0    2021-08-20 [3] CRAN (R 4.1.1)
 pbapply          * 1.7-4    2025-07-20 [1] CRAN (R 4.5.0)
 permute            0.9-8    2025-06-25 [1] CRAN (R 4.5.0)
 PhenotypeSpace   * 0.1.1    2025-07-21 [1] Github (maRce10/PhenotypeSpace@1ee576c)
 pillar             1.11.1   2025-09-17 [1] CRAN (R 4.5.0)
 pkgbuild           1.4.8    2025-05-26 [1] CRAN (R 4.5.0)
 pkgconfig          2.0.3    2019-09-22 [1] CRAN (R 4.5.0)
 pkgload            1.4.1    2025-09-23 [1] CRAN (R 4.5.0)
 plyr               1.8.9    2023-10-02 [1] CRAN (R 4.5.0)
 polyclip           1.10-7   2024-07-23 [1] CRAN (R 4.5.0)
 posterior          1.6.1    2025-02-27 [1] CRAN (R 4.5.0)
 profvis            0.4.0    2024-09-20 [1] CRAN (R 4.5.0)
 promises           1.3.3    2025-05-29 [1] RSPM (R 4.5.0)
 proxy              0.4-27   2022-06-09 [1] CRAN (R 4.5.0)
 purrr              1.2.0    2025-11-04 [1] CRAN (R 4.5.0)
 QuickJSR           1.8.1    2025-09-20 [1] CRAN (R 4.5.0)
 R6                 2.6.1    2025-02-15 [1] CRAN (R 4.5.0)
 raster             3.6-32   2025-03-28 [1] CRAN (R 4.5.0)
 rbibutils          2.3      2024-10-04 [1] CRAN (R 4.5.0)
 RColorBrewer       1.1-3    2022-04-03 [1] CRAN (R 4.5.0)
 Rcpp             * 1.1.0    2025-07-02 [1] CRAN (R 4.5.0)
 RcppParallel       5.1.11-1 2025-08-27 [1] CRAN (R 4.5.0)
 Rdpack             2.6.4    2025-04-09 [1] CRAN (R 4.5.0)
 readxl           * 1.4.5    2025-03-07 [3] CRAN (R 4.5.0)
 reformulas         0.4.1    2025-04-30 [1] CRAN (R 4.5.0)
 remotes          * 2.5.0    2024-03-17 [1] CRAN (R 4.5.0)
 reshape2           1.4.5    2025-11-12 [1] CRAN (R 4.5.0)
 rlang              1.1.6    2025-04-11 [1] CRAN (R 4.5.0)
 rmarkdown          2.30     2025-09-28 [1] CRAN (R 4.5.0)
 rprojroot          2.1.1    2025-08-26 [1] CRAN (R 4.5.0)
 rstan              2.32.7   2025-03-10 [1] CRAN (R 4.5.0)
 rstantools         2.5.0    2025-09-01 [1] CRAN (R 4.5.0)
 rstudioapi         0.17.1   2024-10-22 [1] CRAN (R 4.5.0)
 S7                 0.2.1    2025-11-14 [1] CRAN (R 4.5.0)
 sandwich           3.1-1    2024-09-15 [3] CRAN (R 4.5.0)
 scales             1.4.0    2025-04-24 [1] CRAN (R 4.5.0)
 sessioninfo        1.2.3    2025-02-05 [3] CRAN (R 4.5.0)
 sf                 1.0-22   2025-11-10 [1] CRAN (R 4.5.0)
 shiny              1.10.0   2024-12-14 [1] CRAN (R 4.5.0)
 sketchy            1.0.5    2025-08-20 [1] CRANs (R 4.5.0)
 sp                 2.2-0    2025-02-01 [1] CRAN (R 4.5.0)
 spatstat.data      3.1-6    2025-03-17 [1] CRAN (R 4.5.0)
 spatstat.explore   3.4-3    2025-05-21 [1] CRAN (R 4.5.0)
 spatstat.geom      3.5-0    2025-07-20 [1] CRAN (R 4.5.0)
 spatstat.random    3.4-1    2025-05-20 [1] CRAN (R 4.5.0)
 spatstat.sparse    3.1-0    2024-06-21 [1] CRAN (R 4.5.0)
 spatstat.univar    3.1-4    2025-07-13 [1] CRAN (R 4.5.0)
 spatstat.utils     3.1-5    2025-07-17 [1] CRAN (R 4.5.0)
 StanHeaders        2.32.10  2024-07-15 [1] CRAN (R 4.5.0)
 stringi            1.8.7    2025-03-27 [1] CRAN (R 4.5.0)
 stringr            1.6.0    2025-11-04 [1] CRAN (R 4.5.0)
 survival           3.8-3    2024-12-17 [4] CRAN (R 4.4.2)
 svglite            2.2.2    2025-10-21 [1] CRAN (R 4.5.0)
 svUnit             1.0.8    2025-08-26 [1] CRAN (R 4.5.0)
 systemfonts        1.3.1    2025-10-01 [1] CRAN (R 4.5.0)
 tensor             1.5.1    2025-06-17 [1] CRAN (R 4.5.0)
 tensorA            0.36.2.1 2023-12-13 [1] CRAN (R 4.5.0)
 terra              1.8-80   2025-11-05 [1] CRAN (R 4.5.0)
 textshaping        1.0.4    2025-10-10 [1] CRAN (R 4.5.0)
 TH.data            1.1-3    2025-01-17 [3] CRAN (R 4.5.0)
 tibble             3.3.0    2025-06-08 [1] RSPM (R 4.5.0)
 tidybayes          3.0.7    2024-09-15 [1] CRAN (R 4.5.0)
 tidyr              1.3.1    2024-01-24 [1] CRAN (R 4.5.0)
 tidyselect         1.2.1    2024-03-11 [1] CRAN (R 4.5.0)
 timechange         0.3.0    2024-01-18 [3] CRAN (R 4.5.0)
 units              1.0-0    2025-10-09 [1] CRAN (R 4.5.0)
 urlchecker         1.0.1    2021-11-30 [1] CRAN (R 4.5.0)
 usethis            3.1.0    2024-11-26 [3] CRAN (R 4.5.0)
 V8                 6.0.4    2025-06-04 [1] RSPM (R 4.5.0)
 vctrs              0.6.5    2023-12-01 [1] CRAN (R 4.5.0)
 vegan              2.7-1    2025-06-05 [1] CRAN (R 4.5.0)
 viridis          * 0.6.5    2024-01-29 [1] CRAN (R 4.5.0)
 viridisLite      * 0.4.2    2023-05-02 [1] CRAN (R 4.5.0)
 withr              3.0.2    2024-10-28 [1] CRAN (R 4.5.0)
 xaringanExtra      0.8.0    2024-05-19 [1] CRAN (R 4.5.0)
 xfun               0.54     2025-10-30 [1] CRAN (R 4.5.0)
 xml2               1.5.1    2025-12-01 [1] CRAN (R 4.5.0)
 xtable             1.8-4    2019-04-21 [3] CRAN (R 4.0.1)
 yaml               2.3.11   2025-11-28 [1] CRAN (R 4.5.0)
 zoo                1.8-14   2025-04-10 [3] CRAN (R 4.5.0)

 [1] /home/m/R/x86_64-pc-linux-gnu-library/4.5
 [2] /usr/local/lib/R/site-library
 [3] /usr/lib/R/site-library
 [4] /usr/lib/R/library
 * ── Packages attached to the search path.

──────────────────────────────────────────────────────────────────────────────