## vector with package names
x <- c( "pbapply", "parallel", "ggplot2", "warbleR", "Rraven", "viridis", "readxl", "rptR", "MCMCglmm", "MuMIn", "corrplot", "lme4", "grid", "gridExtra")
aa <- lapply(x, function(y) {
# check if installed, if not then install
if (!y %in% installed.packages()[,"Package"])
install.packages(y)
# load package
try(require(y, character.only = T), silent = T)
})
#functions and parameters
knitr::opts_knit$set(root.dir = normalizePath(".."))
knitr::opts_chunk$set(dpi = 50, fig.width = 12, warning = FALSE, message = FALSE)
# ggplot2 theme
# theme_set(theme_classic(base_size = 20))
cut_path <- "./data/raw/cuts"
treatments <- c("Calibration", "Regular_singing", "Coordination", "After_chase",
"Before_playback", "After_playback", "Before_interaction", "After_interaction", "Before_noise", "After_noise")
# iterations for MCMCglmm models
itrns <- 100000
# functions from https://rdrr.io/rforge/rptR/src/R/rpt.mcmcLMM.R
rpt.mcmcLMM <- function(y, groups, CI=0.95, prior=NULL, verbose=FALSE, ...){
# initial checks
if(length(y)!= length(groups)) stop("y and group are of unequal length")
# preparation
groups <- factor(groups)
if(is.null(prior)) prior <- list(R=list(V=1,n=10e-2), G=list(G1=list(V=1,n=10e-2)) )
# point estimation according to model 8 and equation 9
mod <- MCMCglmm(y ~ 1, random=~groups, family="gaussian", data=data.frame(y=y,groups=groups), prior=prior, verbose=verbose, ...)
var.a <- mod$VCV[,"groups"]
var.e <- mod$VCV[,"units"]
postR <- var.a / (var.a + var.e)
# point estimate
R <- posterior.mode( postR )
# credibility interval estimation from paterior distribution
CI.R <- coda::HPDinterval(postR,CI)[1,]
se <- sd(postR)
# 'significance test'
P <- NA
res = list(call=match.call(), datatype="Gaussian", method="LMM.MCMC", CI=CI,
R=R, CI.R=CI.R, se=se, P=P)
# class(res) <- "rpt"
return(res)
}
## print Gelman-Rubin convergence statistics, plots traces and autocorrelations
mcmc_diagnostics <- function(rep_mods_list){
for(w in 1:length(rep_mods_list))
{
mod_name <- names(rep_mods_list)[w]
if(mod_name == "1") mod_name <- "Null"
print(paste("model:", mod_name))
Y <- lapply(rep_mods_list[[w]], "[[", "Sol")
## add global plots and gelman test
# gelman_diagnostic
gel_diag <- as.data.frame(gelman.diag(mcmc.list(Y))$psrf)
# add estimate as column
gel_diag$estimate <- rownames(gel_diag)
# reorder columns
gel_diag <- gel_diag[, c(3, 1, 2)]
par(mfrow = c(1, 1))
# plot table
grid.newpage()
grid.draw(tableGrob(gel_diag, rows = NULL, theme=ttheme_default(base_size = 25)))
par(mfrow = c(1, 4))
traceplot(Y, col = adjustcolor(c("yellow","blue", "red"), alpha.f = 0.6))
autocorr.plot(x = Y[[1]], auto.layout = FALSE, lwd =4, col = "red")
}
}
amp <- read.csv("./output/calibrated_amplitude_all_songs.csv")
amp$Treatment[amp$Treatment == "Regular_sining"] <- "Regular_singing"
We estimated repeatability using linear mixed models with MCMC sampling (MCMCglmm()
function)
# keep only morning recs, only regular singing and only from 2021
amp_morn <- amp[amp$period == "morning" & amp$year == 2021 & amp$Treatment == "Regular_singing", ]
# keep only males recorded at least twice
count_sf <- table(amp_morn$ID[!duplicated(amp_morn$org.sound.file)])
amp_morn_rep <- amp_morn[amp_morn$ID %in% names(count_sf)[count_sf > 1], ]
max_quantile <- c(0, 1, seq(10, 90, by = 10)) / 100
outliers <- c(0, 1, 2, 5, 10, 20) / 100
rep_grid <- expand.grid(max_quantile = max_quantile, outliers = outliers, only.low.outliers = c(TRUE, FALSE))
repts <- pblapply(1:nrow(rep_grid), cl = 6, function(x){
quant_subet <- lapply(unique(amp_morn_rep$org.sound.file), function(y){
X <- amp_morn_rep[amp_morn_rep$org.sound.file == y, ]
# remove outliers
outlier_quant <- quantile(X$cal.spl, c(rep_grid$outliers[x], 1- rep_grid$outliers[x]))
if (!rep_grid$only.low.outliers[x])
X <- X[X$cal.spl >= outlier_quant[1] & X$cal.spl <= outlier_quant[2],] else X <- X[X$cal.spl >= outlier_quant[1],]
# quantlie for each max quantile
quant <- quantile(X$cal.spl, probs = 1 - rep_grid$max_quantile[x])
# subset
X <- X[X$cal.spl >= quant, ]
})
quant_subet <- do.call(rbind, quant_subet)
# frequentist
# out <- rpt(cal.spl ~ (1 | ID), grname = "ID", data = quant_subet, datatype = "Gaussian", npermut = 0, nboot = 100)
# bayesian
out <- rpt.mcmcLMM(y = quant_subet$cal.spl, groups = quant_subet$ID, nitt = itrns)
out_df <- data.frame(rep_grid$max_quantile[x], rep_grid$outliers[x], rep_grid$only.low.outliers[x], out$R, out$CI.R[1], out$CI.R[2])
return(out_df)
})
repts_df <- do.call(rbind, repts)
names(repts_df) <- c("max_quantile", "outliers", "only.low.outliers", "repeatability", "lowCI", "hiCI")
write.csv(repts_df, "./output/repeatability_optimization.csv", row.names = FALSE)
repts_df <- read.csv("./output/repeatability_optimization.csv")
pd <- position_dodge(width = 0.1)
ggplot(data = repts_df, aes(x = 1 - max_quantile, y = repeatability, color = only.low.outliers, group = only.low.outliers)) +
geom_hline(yintercept = 0.5, col = adjustcolor("red", alpha.f = 0.5)) +
geom_point(size = 2, position = pd) +
geom_errorbar(width=.05, aes(ymin = lowCI, ymax = hiCI), position = pd) +
scale_color_viridis(discrete = TRUE, begin = 0.2, end = 0.8, alpha = 0.7) +
geom_line(position = pd) +
labs(y = "Repeatability", x = "Upper quantile used") +
ylim(c(0, 1)) + xlim(c(1, 0)) +
facet_wrap(~ outliers, scales = "fixed") +
theme_classic(base_size = 24)
repts_df$range <- repts_df$hiCI - repts_df$lowCI
# repts_df[order(repts_df$repeatability), c("max_quantile", "outliers", "only.low.outliers", "repeatability", "range")]
repts_df <- repts_df[order(repts_df$repeatability, decreasing = TRUE), ]
kable(head(repts_df))
max_quantile | outliers | only.low.outliers | repeatability | lowCI | hiCI | range | |
---|---|---|---|---|---|---|---|
116 | 0.4 | 0.10 | FALSE | 0.5790952 | 0.2912715 | 0.8124867 | 0.5212152 |
120 | 0.8 | 0.10 | FALSE | 0.5760627 | 0.2933315 | 0.8183214 | 0.5249900 |
86 | 0.7 | 0.01 | FALSE | 0.5742588 | 0.2970074 | 0.8256426 | 0.5286352 |
52 | 0.6 | 0.10 | TRUE | 0.5679999 | 0.2918631 | 0.8131767 | 0.5213137 |
6 | 0.4 | 0.00 | TRUE | 0.5633166 | 0.2903133 | 0.8141992 | 0.5238859 |
106 | 0.5 | 0.05 | FALSE | 0.5549716 | 0.2926263 | 0.8167255 | 0.5240992 |
Subsetting the 0.4 upper quartile after excluding 0.2 lower tail outliers:
# compose variable to remove low values and outliers based on repeatabiliy
amp$osf.treat <- paste(amp$org.sound.file, amp$Treatment, sep = "-")
rm_outlier_amp_l <- lapply(unique(amp$osf.treat), function(y){
X <- amp[amp$osf.treat == y, ]
# remove outliers
outlier_quant <- quantile(X$cal.spl, c(repts_df$outliers[1], 1))
X <- X[X$cal.spl >= outlier_quant[1] & X$cal.spl <= outlier_quant[2],]
# quantlie for each max quantile (0.6 was selected due to high repeatability)
quant <- quantile(X$cal.spl, probs = repts_df$max_quantile[1])
# subset
X <- X[X$cal.spl >= quant, ]
})
rm_outlier_amp <- do.call(rbind, rm_outlier_amp_l)
We use bayesian MCMC generalized linear models with individual ID and song type as random factors (random intercepts) except indicated. An intercept-only (null) model is also included in the analyses. A loop is used to run these models. Each model is replicated three times with starting values sampled from a Z-distribution (“start” argument in MCMCglmm()). Diagnostic plots for MCMC model performance are shown at the end of this report.
# subset data
period_data <- rm_outlier_amp[rm_outlier_amp$Treatment == "Regular_singing" & rm_outlier_amp$year == 2021 & rm_outlier_amp$ID %in% unique(rm_outlier_amp$ID[rm_outlier_amp$period == "afternoon"]), ]
# model SPL by body size
period_formulas <- c("cal.spl ~ 1", "cal.spl ~ period")
period_mods <- pblapply(period_formulas, function(x){
replicate(n = 3, MCMCglmm(as.formula(x), random = ~ ID + songtype, data = period_data, verbose = FALSE, nitt = itrns, start = list(QUASI = FALSE)), simplify = FALSE)
})
names(period_mods) <- gsub("cal.spl ~ ", "", period_formulas)
saveRDS(list(period_formulas = period_formulas, period_mods = period_mods), "./output/mcmcglmm_period_models.RDS")
attach(readRDS("./output/mcmcglmm_period_models.RDS"))
mod_list <- lapply(period_mods, "[[", 1)
names(mod_list) <- gsub("cal.spl ~ ", "", period_formulas)
model_selection <- model.sel(mod_list, rank="DIC")
model_selection
(Intercept) | period | family | df | logLik | DIC | delta | weight | |
---|---|---|---|---|---|---|---|---|
period | 98.38209 | + | (NA) | 5 | -6192.009 | 12389.99 | 0.00000 | 1.000000e+00 |
1 | 99.28286 | NA | (NA) | 4 | -6223.692 | 12452.40 | 62.40826 | 2.806839e-14 |
# fixed effects with HPD intervals
best_mod_period <- period_mods[[which(names(period_mods) == row.names(model_selection)[1])]][[1]]
sm <- as.data.frame(summary(best_mod_period)$solutions[, -5])
sm
post.mean | l-95% CI | u-95% CI | eff.samp | |
---|---|---|---|---|
(Intercept) | 98.382089 | 90.2424713 | 106.17904 | 4700 |
periodmorning | 1.232936 | 0.9223919 | 1.52236 | 4700 |
dat_period <- rm_outlier_amp[rm_outlier_amp$Treatment == "Regular_singing" & rm_outlier_amp$ID %in% unique(rm_outlier_amp$ID[rm_outlier_amp$period == "afternoon"]), ]
dat_period$period <- factor(dat_period$period, levels = c("morning", "afternoon"))
ggplot(dat_period, aes(x = as.factor(ID), y = cal.spl, color = period, fill = period)) +
geom_violin(position = pd) +
labs(x = "Individual", y = "Sound pressure level (dB)", fill = "Period") +
scale_color_viridis_d(begin = 0.1, end = 0.8, alpha = 0.6) +
scale_fill_viridis_d(begin = 0.1, end = 0.8, alpha = 0.6) +
guides(color = FALSE) +
theme_classic(base_size = 24)
Effect size posterior distribution
# simplify names
colnames(best_mod_period$Sol) <- c("Intercept", "Morning vs afternoon")
# stack posteriors
Y <- stack(as.data.frame(best_mod_period$Sol[, -1]))
Y$ind <- "Morning vs afternoon"
# plot posteriors
ggplot(Y, aes(y=values, x = ind)) +
geom_hline(yintercept = 0, col = "red", lty = 2) +
geom_violin(color = "gray40", fill = viridis(n = 1, alpha = 0.25, begin = 0.4)) +
labs(y = "Effect size posterior distribution",x = "Predictor") +
theme_classic(base_size = 24) +
theme(axis.text.x = element_text(angle = 45, vjust = 0.9, hjust=1))
Body size as predictor: \[SPL \sim + body\ size + (1 | individual) + (1 | song\ type)\]
Lifting power as predictor: \[SPL \sim + lifting\ power + (1 | individual) + (1 | song\ type)\]
Lifting power and body size as predictors: \[SPL \sim + lifting\ power + body\ size + (1 | individual) + (1 | song\ type)\]
Interaction of lifting power and body size as predictor: \[SPL \sim + lifting\ power * body\ size + (1 | individual) + (1 | song\ type)\]
Null model with no predictor (intercept only): \[SPL \sim + 1 + (1 | individual) + (1 | song\ type)\]
caps <- read_excel("/home/m/Dropbox/LBH data/Additional data files/LBH captures data.xlsx")
# same variables as in paper on spatial memory and body size
size_vars <- caps[caps$`Bird ID` %in% amp$ID, c("Bird ID", "Total culmen", "Flattened wing length", "Weight", "Central rectriz")]
# replace 419 central rectriz with mean
size_vars$`Central rectriz`[size_vars$`Bird ID` == 419] <- mean(size_vars$`Central rectriz`, na.rm = TRUE)
cor(size_vars[, c("Total culmen", "Flattened wing length", "Weight", "Central rectriz")], use = "pairwise.complete.obs")
## Total culmen Flattened wing length Weight
## Total culmen 1.000000000 -0.13969106 0.14426785
## Flattened wing length -0.139691059 1.00000000 0.08646515
## Weight 0.144267849 0.08646515 1.00000000
## Central rectriz 0.007536892 0.34107800 0.10235729
## Central rectriz
## Total culmen 0.007536892
## Flattened wing length 0.341077996
## Weight 0.102357292
## Central rectriz 1.000000000
mean_size <- aggregate(. ~ `Bird ID`, data = size_vars, FUN = mean, na.action = "na.omit")
pca <- prcomp(mean_size[, c("Total culmen", "Flattened wing length", "Weight", "Central rectriz")], scale. = TRUE)
summary(pca)
## Importance of components:
## PC1 PC2 PC3 PC4
## Standard deviation 1.2488 1.0841 0.8726 0.7098
## Proportion of Variance 0.3899 0.2938 0.1903 0.1259
## Cumulative Proportion 0.3899 0.6837 0.8741 1.0000
mean_size$PC1 <- pca$x[, 1]
rm_outlier_amp$PC1 <- sapply(1:nrow(rm_outlier_amp), function(x) mean_size$PC1[mean_size$`Bird ID` == rm_outlier_amp$ID[x]][1])
rm_outlier_amp$weight <- sapply(1:nrow(rm_outlier_amp), function(x) mean_size$Weight[mean_size$`Bird ID` == rm_outlier_amp$ID[x]][1])
### add weight lifted
lift <- read_excel("/home/m/Dropbox/LBH data/Morphology-condition/other files/Uplift power experiment.xlsx", sheet = "Results")
rm_outlier_amp$lift.weight <- sapply(1:nrow(rm_outlier_amp), function(x){
if(rm_outlier_amp$ID[x] == 0) weight <- NA else {
if (rm_outlier_amp$year[x] == 2019)
sub_lift <- lift[grep("\\.2019\\.", lift$Video), ] else
sub_lift <- lift[grep("\\.2021\\.", lift$Video), ]
weights <- sub_lift$Weight[sub_lift$ID == rm_outlier_amp$ID[x]]
if (length(weights) > 0)
# get the mean of the 2 highest flights
weight <- mean(sort(weights, decreasing = TRUE)[1:2]) else
weight <- NA
}
return(weight)
})
# subset data
body_size_data <- rm_outlier_amp[rm_outlier_amp$Treatment == "Regular_singing" & rm_outlier_amp$year == 2021 & !is.na(rm_outlier_amp$PC1) & !is.na(rm_outlier_amp$lift.weight) & rm_outlier_amp$period == "morning", ]
# model SPL by body condition
size_formulas <- c("cal.spl ~ 1", "cal.spl ~ PC1", "cal.spl ~ lift.weight", "cal.spl ~ lift.weight + PC1", "cal.spl ~ lift.weight * PC1")
size_mods <- pblapply(size_formulas, function(x){
replicate(n = 3, MCMCglmm(as.formula(x), random = ~ ID + songtype, data = body_size_data, verbose = FALSE, nitt = itrns, start = list(QUASI = FALSE)), simplify = FALSE)
})
names(size_mods) <- gsub("cal.spl ~ ", "", size_formulas)
saveRDS(list(size_formulas = size_formulas, size_mods = size_mods), "./output/mcmcglmm_size_models.RDS")
attach(readRDS("./output/mcmcglmm_size_models.RDS"))
mod_list <- lapply(size_mods, "[[", 1)
names(mod_list) <- gsub("cal.spl ~ ", "", size_formulas)
model_selection <- model.sel(mod_list, rank="DIC")
model_selection
(Intercept) | PC1 | lift.weight | lift.weight:PC1 | family | df | logLik | DIC | delta | weight | |
---|---|---|---|---|---|---|---|---|---|---|
PC1 | 101.09190 | 1.0046808 | NA | NA | (NA) | 5 | -19465.59 | 38951.93 | 0.0000000 | 0.2097915 |
lift.weight * PC1 | 77.00884 | 10.1703441 | 1.523415 | -0.6213227 | (NA) | 7 | -19465.47 | 38951.96 | 0.0295211 | 0.2067176 |
lift.weight + PC1 | 84.96609 | 0.7948061 | 1.007591 | NA | (NA) | 6 | -19465.58 | 38952.07 | 0.1427185 | 0.1953426 |
lift.weight | 84.09664 | NA | 1.075396 | NA | (NA) | 5 | -19465.63 | 38952.08 | 0.1527718 | 0.1943631 |
1 | 101.30179 | NA | NA | NA | (NA) | 4 | -19465.59 | 38952.09 | 0.1587259 | 0.1937853 |
None of the models provided a better fit compared to the null model
# fixed effects with HPD intervals
best_mod_size <- size_mods[[which(names(size_mods) == "lift.weight + PC1")]][[1]]
sm_size <- as.data.frame(summary(best_mod_size)$solutions[, -5])
sm_size
post.mean | l-95% CI | u-95% CI | eff.samp | |
---|---|---|---|---|
(Intercept) | 84.9660852 | 48.977501 | 122.674261 | 9700.000 |
lift.weight | 1.0075913 | -1.218165 | 3.364722 | 9700.000 |
PC1 | 0.7948061 | -2.060258 | 3.951657 | 9391.704 |
body_size_data <- rm_outlier_amp[rm_outlier_amp$Treatment == "Regular_singing" & rm_outlier_amp$year == 2021 & !is.na(rm_outlier_amp$PC1) & !is.na(rm_outlier_amp$lift.weight) & rm_outlier_amp$period == "morning", ]
agg_size <- aggregate(cbind(cal.spl, lift.weight, PC1) ~ ID, data = body_size_data, mean)
agg_size$count <- aggregate(PC1 ~ ID, data = body_size_data, length)$PC1
ggplot(agg_size, aes(x = PC1, y = cal.spl)) +
geom_jitter(position = position_jitter(width = 0.2, height = 0.2), aes(size = count)) +
labs(x = "Body size (PC1)", y = "Sound pressure level (dB)", color = "Period", size = "Sample size") +
scale_color_viridis_d(begin = 0.1, end = 0.8, alpha = 0.7) +
theme_classic(base_size = 24) +
# geom_abline(slope = c(ES_continious = sm_size[2, 1], ES_continious_plus_ES_interaction= sm_size[2, 1] + sm_size[4, 1]), intercept = c(intercept = sm_size[1, 1], intercept_plus_ES_categorical = sm_size[1, 1] + sm_size[3, 1]), color = viridis(2, begin = 0.2, end = 0.8, alpha = 0.6)[2:1], size = 1) +
guides(colour = guide_legend(override.aes = list(size=8)))
ggplot(agg_size, aes(x = lift.weight, y = cal.spl)) +
geom_jitter(position = position_jitter(width = 0.2, height = 0.2), aes(size = count)) +
labs(x = "Lifiting power (g)", y = "Sound pressure level (dB)", color = "Period", size = "Sample size") +
scale_color_viridis_d(begin = 0.1, end = 0.8, alpha = 0.7) +
theme_classic(base_size = 24) +
# geom_abline(slope = c(ES_continious = sm_size[2, 1], ES_continious_plus_ES_interaction= sm_size[2, 1] + sm_size[4, 1]), intercept = c(intercept = sm_size[1, 1], intercept_plus_ES_categorical = sm_size[1, 1] + sm_size[3, 1]), color = viridis(2, begin = 0.2, end = 0.8, alpha = 0.6)[2:1], size = 1) +
guides(colour = guide_legend(override.aes = list(size=8)))
Effect size posterior distribution
# simplify names
colnames(best_mod_size$Sol) <- c("Intercept", "lifted weight","Body size (PC1)")
# stack posteriors
Y <- stack(as.data.frame(best_mod_size$Sol[, -1]))
# plot posteriors
ggplot(Y, aes(y=values, x = ind)) +
geom_hline(yintercept = 0, col = "red", lty = 2) +
geom_violin(color = "gray40", fill = viridis(n = 1, alpha = 0.25, begin = 0.4)) +
labs(y = "Effect size posterior distribution", x = "Predictor") +
theme_classic(base_size = 24) +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))
Playback as predictor and random slope: \[SPL \sim + playback + (playback | individual)\]
Playback and body size interaction as predictor and random intercept: \[SPL \sim + playback * body\ size + (1 | individual) \]
Playback and lifting power interaction as predictor and random intercept: \[SPL \sim + playback * lifting\ power + (1 | individual) \]
Playback as predictor and only random intercept: \[SPL \sim + playback + (1 | individual) + (1 | song\ type)\]
Null model with no predictor (random intercept only): \[SPL \sim + 1 + (1 | individual) + (1 | song\ type)\]
playback_dat <- rm_outlier_amp[rm_outlier_amp$Treatment %in% c("Before_playback", "After_playback"), ]
# label 2019 recordings
playback_dat$ID <- ifelse(grepl("2019", playback_dat$org.sound.file), paste(playback_dat$ID, "(2019)"), playback_dat$ID)
# remove indiviudal recorded in 2019 and 2021
playback_dat <- playback_dat[playback_dat$ID != "397 (2019)", ]
random_slope_mod <- lmer(cal.spl ~ Treatment + (Treatment|ID), data = playback_dat, REML = FALSE)
interaction_size_mod <- lmer(cal.spl ~ PC1 + Treatment + PC1:Treatment + (1|ID), data = playback_dat, REML = FALSE)
interaction_lift_mod <- lmer(cal.spl ~ PC1 + lift.weight + PC1:lift.weight + (1|ID), data = playback_dat, REML = FALSE)
random_intercept_only_mod <- lmer(cal.spl ~ Treatment + (1|ID) + (1|songtype), data = playback_dat, REML = FALSE)
null_mod <- lmer(cal.spl ~ 1 + (1|ID) + (1|songtype), data = playback_dat, REML = FALSE)
d1 <- (-2*logLik(random_intercept_only_mod)) + (2*logLik(random_slope_mod))
pval_rand_slope_vs_rand_intercept <- 0.5*pchisq(d1[1], 0, lower.tail=FALSE) + 0.5*pchisq(d1[1], 1, lower.tail=FALSE)
d2 <- (-2*logLik(null_mod)) + (2*logLik(random_intercept_only_mod))
pval_rand_intercept_vs_null <- 0.5*pchisq(d2[1], 0, lower.tail=FALSE) + 0.5*pchisq(d2[1], 1, lower.tail=FALSE)
d3 <- (-2*logLik(null_mod)) + (2*logLik(random_slope_mod))
pval_rand_slope_vs_null <- 0.5*pchisq(d3[1], 0, lower.tail=FALSE) + 0.5*pchisq(d3[1], 1, lower.tail=FALSE)
d4 <- (-2*logLik(interaction_size_mod)) + (2*logLik(random_slope_mod))
pval_rand_slope_vs_interaction_size <- 0.5*pchisq(d4[1], 0, lower.tail=FALSE) + 0.5*pchisq(d4[1], 1, lower.tail=FALSE)
d5 <- (-2*logLik(interaction_lift_mod)) + (2*logLik(random_slope_mod))
pval_rand_slope_vs_interaction_lift <- 0.5*pchisq(d5[1], 0, lower.tail=FALSE) + 0.5*pchisq(d5[1], 1, lower.tail=FALSE)
agg_playback <- aggregate(cal.spl ~ Treatment + ID, data = playback_dat, mean)
agg_playback$sd <- aggregate(cal.spl ~ Treatment + ID, data = playback_dat, sd)$cal.spl
agg_playback$Treatment <- factor(gsub("_playback", "", agg_playback$Treatment), levels = c("Before", "After"))
ggplot(agg_playback, aes(x = Treatment, y = cal.spl, color = Treatment)) +
geom_point(size = 2, show.legend = FALSE) +
geom_errorbar(width=.05, aes(ymin = cal.spl - sd, ymax = cal.spl + sd), show.legend = FALSE) +
labs(x = "Playback treatment", y = "Sound pressure level (dB)", color = "Period") +
scale_color_viridis_d(begin = 0.1, end = 0.8, alpha = 1) +
facet_wrap(~ ID, nrow = 3, scales = "free_y") +
theme_classic(base_size = 24)
Coordination as predictor and random slope: \[SPL \sim + coordination + (coordination | individual)\]
Coordination as predictor and random intercept only: \[SPL \sim + coordination + (1 | individual)\]
Null model with no predictor (random intercept only): \[SPL \sim + 1 + (1 | individual)\]
# fixed effects with HPD intervals
coord_data <- rm_outlier_amp[rm_outlier_amp$org.sound.file %in% rm_outlier_amp$org.sound.file[rm_outlier_amp$Treatment == "Coordination"], ]
coord_data <- coord_data[coord_data$Treatment %in% c("Regular_singing","Coordination"), ]
random_slope_mod <- lmer(cal.spl ~ Treatment + (Treatment|ID), data = coord_data, REML = FALSE)
random_intercept_only_mod <- lmer(cal.spl ~ Treatment + (1|ID), data = coord_data, REML = FALSE)
null_mod <- lmer(cal.spl ~ 1 + (1|ID), data = coord_data, REML = FALSE)
d1 <- (-2*logLik(random_intercept_only_mod)) + (2*logLik(random_slope_mod))
random_slope_vs_random_intercept <- 0.5*pchisq(d1[1], 0, lower.tail=FALSE) + 0.5*pchisq(d1[1], 1, lower.tail=FALSE)
d2 <- (-2*logLik(null_mod)) + (2*logLik(random_intercept_only_mod))
random_intercept_vs_null <- 0.5*pchisq(d2[1], 0, lower.tail=FALSE) + 0.5*pchisq(d2[1], 1, lower.tail=FALSE)
d3 <- (-2*logLik(null_mod)) + (2*logLik(random_slope_mod))
random_slope_vs_null <- 0.5*pchisq(d3[1], 0, lower.tail=FALSE) + 0.5*pchisq(d3[1], 1, lower.tail=FALSE)
agg_coord <- aggregate(cal.spl ~ Treatment + ID, data = coord_data, mean)
agg_coord$sd <- aggregate(cal.spl ~ Treatment + ID, data = coord_data, sd)$cal.spl
agg_coord$Treatment <- factor(ifelse(agg_coord$Treatment == "Coordination", "Coordinated", "Solo"), levels = c("Solo", "Coordinated"))
ggplot(agg_coord, aes(x = Treatment, y = cal.spl, color = Treatment)) +
geom_point(size = 2, show.legend = FALSE) +
geom_errorbar(width=.05, aes(ymin = cal.spl - sd, ymax = cal.spl + sd), show.legend = FALSE) +
labs(x = "coord treatment", y = "Sound pressure level (dB)", color = "Period") +
scale_color_viridis_d(begin = 0.1, end = 0.8, alpha = 1) +
facet_wrap(~ ID, nrow = 2, scales = "free_y") +
theme_classic(base_size = 24)
# subset data
dat_chase <- rm_outlier_amp[rm_outlier_amp$org.sound.file %in% rm_outlier_amp$org.sound.file[rm_outlier_amp$Treatment == "After_chase"], ]
dat_chase <- dat_chase[dat_chase$Treatment %in% c("Regular_singing", "After_chase"),]
dat_chase$inter_treatment <- ifelse(grepl("After", dat_chase$Treatment), "2_After", "1_Before")
dat_chase$inter_type <- "2_Chase"
dat_interaction <- rm_outlier_amp[rm_outlier_amp$Treatment %in% c("After_interaction", "Before_interaction"), ]
dat_interaction$inter_treatment <- ifelse(grepl("After", dat_interaction$Treatment), "2_After", "1_Before")
dat_interaction$inter_type <- "1_Perch_interaction"
# fix range of non-calibrated recs
dat_interaction$cal.spl[dat_interaction$year < 2021] <- dat_interaction$cal.spl[dat_interaction$year < 2021] + mean(dat_interaction$cal.spl[dat_interaction$year == 2021]) - mean(dat_interaction$cal.spl[dat_interaction$year < 2021])
dat_aggresive_inter <- rbind(dat_interaction, dat_chase)
# fix low value one
dat_aggresive_inter$cal.spl[dat_aggresive_inter$sound.files == dat_aggresive_inter$sound.files[which.min(dat_aggresive_inter$cal.spl)]] <- dat_aggresive_inter$cal.spl[dat_aggresive_inter$sound.files == dat_aggresive_inter$sound.files[which.min(dat_aggresive_inter$cal.spl)]] + mean(dat_aggresive_inter$cal.spl[dat_aggresive_inter$sound.files != dat_aggresive_inter$sound.files[which.min(dat_aggresive_inter$cal.spl)]]) - mean(dat_aggresive_inter$cal.spl[dat_aggresive_inter$sound.files == dat_aggresive_inter$sound.files[which.min(dat_aggresive_inter$cal.spl)]])
# table(dat_aggresive_inter$ID, dat_aggresive_inter$inter_treatment, dat_aggresive_inter$inter_type)
# model SPL by interaction
interaction_formulas <- c("cal.spl ~ 1", "cal.spl ~ inter_treatment", "cal.spl ~ inter_treatment + inter_type", "cal.spl ~ inter_treatment * inter_type")
# dat_aggresive_inter$inter_treatment <- factor(dat_aggresive_inter$inter_treatment, levels = c("After", "Before"))
# dat_aggresive_inter$inter_type <- factor(dat_aggresive_inter$inter_type, levels = c("Perch interaction", "Chase"))
inter_mods <- pblapply(interaction_formulas, function(x){
replicate(n = 3, MCMCglmm(as.formula(x), random = ~ ID, data = dat_aggresive_inter, verbose = FALSE, nitt = itrns, start = list(QUASI = FALSE)), simplify = FALSE)
})
names(inter_mods) <- gsub("cal.spl ~ ", "", interaction_formulas)
saveRDS(list(interaction_formulas = interaction_formulas, inter_mods = inter_mods), "./output/mcmcglmm_interaction_models.RDS")
attach(readRDS("./output/mcmcglmm_interaction_models.RDS"))
mod_list <- lapply(inter_mods, "[[", 1)
names(mod_list) <- gsub("cal.spl ~ ", "", interaction_formulas)
model_selection <- model.sel(mod_list, rank="DIC")
model_selection
(Intercept) | inter_treatment | inter_type | inter_treatment:inter_type | family | df | logLik | DIC | delta | weight | |
---|---|---|---|---|---|---|---|---|---|---|
inter_treatment * inter_type | 100.40099 | + | + | + | (NA) | 6 | -3020.352 | 6062.358 | 0.00000 | 1.000000e+00 |
inter_treatment + inter_type | 99.66253 | + | + | NA | (NA) | 5 | -3057.029 | 6134.672 | 72.31389 | 1.982618e-16 |
inter_treatment | 100.08454 | + | NA | NA | (NA) | 4 | -3072.151 | 6163.933 | 101.57488 | 8.775953e-23 |
1 | 101.15672 | NA | NA | NA | (NA) | 3 | -3158.309 | 6335.201 | 272.84253 | 5.662346e-60 |
# fixed effects with HPD intervals
best_mod_interaction <- inter_mods[[which(names(inter_mods) == row.names(model_selection)[1])]][[1]]
sm_interaction <- as.data.frame(summary(best_mod_interaction)$solutions[, -5])
sm_interaction
post.mean | l-95% CI | u-95% CI | eff.samp | |
---|---|---|---|---|
(Intercept) | 100.400990 | 98.4147789 | 102.329394 | 9700 |
inter_treatment2_After | 1.265453 | 0.7989197 | 1.747272 | 9700 |
inter_type2_Chase | 1.004035 | 0.3499950 | 1.652210 | 9700 |
inter_treatment2_After:inter_type2_Chase | 3.121944 | 2.4057612 | 3.805274 | 9700 |
# subset data
# dat_aggresive_inter$inter_treatment <- factor(dat_aggresive_inter$inter_treatment, levels = c("1_Before", "2_After"))
dat_aggresive_inter$year <- factor(dat_aggresive_inter$year, levels = c("2013", "2014", "2019", "2021"))
# dat_aggresive_inter$inter_type <- gsub("_", " ", dat_aggresive_inter$inter_type)
# dat_aggresive_inter$inter_type <- factor(dat_aggresive_inter$inter_type, levels = c("1_Perch_interaction", "2_Chase"))
agg_aggresive_inter <- aggregate(cal.spl ~ ID + inter_type + inter_treatment + year, data = dat_aggresive_inter, mean)
agg_aggresive_inter$ID <- as.character(agg_aggresive_inter$ID)
ggplot(dat_aggresive_inter, aes(x = inter_treatment, y = cal.spl)) +
geom_violin(color = "gray40", fill = viridis(n = 1, alpha = 0.25, begin = 0.4)) +
geom_point(size = 4, data = agg_aggresive_inter, aes(group = ID, color = year)) +
geom_line(data = agg_aggresive_inter, aes(group = ID, color = year)) +
labs(x = "Context", y = "Sound pressure level (dB)") +
facet_wrap(~ inter_type) +
scale_color_viridis_d(begin = 0.1, end = 0.8, alpha = 0.7) +
theme_classic(base_size = 24)
Effect size posterior distribution
# extract mcmcs
mcmcs <- best_mod_interaction$Sol
# make empty list
mcmc_l <- list()
## perch interaction before playback
mcmc_l[[length(mcmc_l) + 1]] <- data.frame(spl = mcmcs[,"(Intercept)"], treatment = "Before", type = "Perch interaction")
## perch interaction after playback
mcmc_l[[length(mcmc_l) + 1]] <- data.frame(spl = mcmcs[,"(Intercept)"] + mcmcs[,"inter_treatment2_After"], treatment = "After", type = "Perch interaction"
)
# chase before playback
mcmc_l[[length(mcmc_l) + 1]] <- data.frame(spl = mcmcs[,"(Intercept)"] +
mcmcs[,"inter_type2_Chase"], treatment = "Before", type = "Chase"
)
# chase after playback
mcmc_l[[length(mcmc_l) + 1]] <- data.frame(spl = mcmcs[,"(Intercept)"] +
mcmcs[,"inter_type2_Chase"] +
mcmcs[, "inter_treatment2_After:inter_type2_Chase"], treatment = "After", type = "Chase")
mcmc_df <- do.call(rbind, mcmc_l)
colnames(mcmc_df)[1] <- "spl"
mcmc_df$treatment_type <- paste(mcmc_df$treatment, mcmc_df$type, sep = "-")
# p-values
combs <- combn(x = unique(mcmc_df$treatment_type), m = 2)[, c(1, 6)]
pvals_l <- lapply(1:ncol(combs), function(x){
mcmc1 <- mcmc_df$spl[mcmc_df$treatment_type == combs[1, x]]
mcmc2 <- mcmc_df$spl[mcmc_df$treatment_type == combs[2, x]]
p <- if (mean(mcmc2) > mean(mcmc1))
sum(mcmc1 > mcmc2) / length(mcmc1) else
sum(mcmc2 > mcmc1) / length(mcmc1)
out <- data.frame(mcmc1 = combs[1, x], mcmc2 = combs[2, x], p = p)
return(out)
})
pvals <- do.call(rbind, pvals_l)
mcmc_df$treatment <-factor(mcmc_df$treatment, levels = c("Before", "After"))
mcmc_df$type <-factor(mcmc_df$type, levels = c("Perch interaction", "Chase"))
# plot posteriors
ggplot(mcmc_df, aes(y=spl, x = treatment)) +
# geom_hline(yintercept = 0, col = "red", lty = 2) +
geom_violin(color = "gray40", fill = viridis(n = 1, alpha = 0.25, begin = 0.4)) +
labs(y = "SPL posterior distribution",x = "Predictor") +
theme_classic(base_size = 24) +
facet_wrap(~ type) +
theme(axis.text.x = element_text(angle = 45, vjust = 0.9, hjust=1))
kable(pvals)
mcmc1 | mcmc2 | p |
---|---|---|
Before-Perch interaction | After-Perch interaction | 0 |
Before-Chase | After-Chase | 0 |
Song structure measured as spectrographic consistency and gap duration
agg_amp_inter <- aggregate(cal.spl ~ ID + inter_type, data = dat_aggresive_inter[dat_aggresive_inter$inter_treatment == "2_After" & dat_aggresive_inter$extsn != "mp3",], mean)
agg_amp_inter$amp.change <- agg_amp_inter$cal.spl -
aggregate(cal.spl ~ ID + inter_type, data = dat_aggresive_inter[dat_aggresive_inter$inter_treatment == "1_Before" & dat_aggresive_inter$extsn != "mp3",], mean)$cal.spl
# sort by change
agg_amp_inter <- agg_amp_inter[order(agg_amp_inter$amp.change, decreasing = TRUE), ]
# subset data
dat_song_consistency <- dat_aggresive_inter[dat_aggresive_inter$ID %in% agg_amp_inter$ID[agg_amp_inter$amp.change >= 0.5], ]
dat_song_consistency$ID.treatment <- paste(dat_song_consistency$ID, dat_song_consistency$inter_treatment, sep ="-")
dat_song_consistency_l <- lapply(unique(dat_song_consistency$ID.treatment), function(x){
X <- dat_song_consistency[dat_song_consistency$ID.treatment == x, ]
print(x)
if(nrow(X) > 1){
# measure cross-correlation
xcrr <- (cross_correlation(X, path = "./data/raw/cuts", pb = FALSE, wl = 150))
# measure gaps
gps <- gaps(X, pb = FALSE)$gaps
gps <- gps[gps < 1]
mean.gaps <- mean(gps, na.rm = TRUE)
# mean xcorr
if (!is.na(xcrr[1])){
xcrr <- mean(xcrr[lower.tri(xcrr)])
}
out_df <- data.frame(sound.files = x, ID = X$ID[1], Treatment = X$Treatment[1], xcrr = xcrr, mean.gaps = mean.gaps, mean.spl = mean(X$cal.spl), songtype = X$songtype[1], treatment = X$inter_treatment[1])
} else
out_df <- data.frame(sound.files = x, ID = X$ID[1], Treatment = X$Treatment[1], xcrr = NA, mean.gaps = NA, mean.spl = mean(X$cal.spl), songtype = X$songtype[1], treatment = X$inter_treatment[1])
return(out_df)
})
dat_song_consistency <- do.call(rbind, dat_song_consistency_l)
dat_song_consistency <- dat_song_consistency[!is.na(dat_song_consistency$xcrr), ]
saveRDS(dat_song_consistency, "./output/dat_song_spectrographic_consistency_and_gaps.RDS")
dat_song_consistency <- readRDS("./output/dat_song_spectrographic_consistency_and_gaps.RDS")
# model SPL by body size
song_consistency_formulas <- c("xcrr ~ 1", "xcrr ~ treatment", "xcrr ~ treatment + mean.spl", "xcrr ~ treatment * mean.spl" , "xcrr ~mean.spl")
song_consistency_mods <- pblapply(song_consistency_formulas, function(x){
replicate(n = 3, MCMCglmm(as.formula(x), random = ~ ID + songtype, data = dat_song_consistency, verbose = FALSE, nitt = itrns, start = list(QUASI = FALSE)), simplify = FALSE)
})
names(song_consistency_mods) <- gsub("cal.spl ~ ", "", song_consistency_formulas)
saveRDS(list(song_consistency_formulas = song_consistency_formulas, song_consistency_mods = song_consistency_mods), "./output/mcmcglmm_song_consistency_models.RDS")
attach(readRDS("./output/mcmcglmm_song_consistency_models.RDS"))
mod_list <- lapply(song_consistency_mods, "[[", 1)
names(mod_list) <- gsub("cal.spl ~ ", "", song_consistency_formulas)
model_selection <- model.sel(mod_list, rank="DIC")
model_selection
(Intercept) | treatment | mean.spl | mean.spl:treatment | family | df | logLik | DIC | delta | weight | |
---|---|---|---|---|---|---|---|---|---|---|
xcrr ~ treatment | 0.7255519 | + | NA | NA | (NA) | 5 | 22.10251 | -39.67280 | 0.0000000 | 0.3600905 |
xcrr ~ 1 | 0.7419545 | NA | NA | NA | (NA) | 4 | 21.48487 | -39.15445 | 0.5183422 | 0.2778786 |
xcrr ~ treatment + mean.spl | 0.7170405 | + | -0.0063874 | NA | (NA) | 6 | 21.35235 | -38.20927 | 1.4635309 | 0.1732248 |
xcrr ~mean.spl | 0.7409975 | NA | -0.0049058 | NA | (NA) | 5 | 20.71608 | -37.77691 | 1.8958865 | 0.1395485 |
xcrr ~ treatment * mean.spl | 0.7167435 | + | -0.0072560 | + | (NA) | 7 | 20.40215 | -35.69422 | 3.9785794 | 0.0492577 |
# summary
best_mod_song_consistency <- song_consistency_mods[[which(names(song_consistency_mods) == row.names(model_selection)[1])]][[1]]
sm_song_consistency <- as.data.frame(summary(best_mod_song_consistency)$solutions)
sm_song_consistency[,- 5]
post.mean | l-95% CI | u-95% CI | eff.samp | |
---|---|---|---|---|
(Intercept) | 0.7255519 | 0.6577871 | 0.7976582 | 10109.16 |
treatmentBefore | 0.0321469 | -0.0364210 | 0.0982015 | 9700.00 |
dat_song_consistency <- readRDS("./output/dat_song_spectrographic_consistency_and_gaps.RDS")
# subset data
dat_song_consistency$ID <- as.character(dat_song_consistency$ID)
ggplot(dat_song_consistency, aes(x = mean.spl, y = xcrr)) +
geom_point(size = 4, color = viridis(5, alpha = 0.5)[3]) +
labs(y = "Mean cross-correlation", x = "Sound pressure level (dB)") +
scale_color_viridis_d(begin = 0.1, end = 0.8, alpha = 0.7) +
theme_classic(base_size = 24)
# stack posteriors
Y <- stack(as.data.frame(best_mod_song_consistency$Sol))
# Y$ind <- "mean.spl"
# plot posteriors
ggplot(Y, aes(y=values, x = ind)) +
geom_hline(yintercept = 0, col = "red", lty = 2) +
geom_violin(color = "gray40", fill = viridis(n = 1, alpha = 0.25, begin = 0.4)) +
labs(y = "Effect size posterior distribution",x = "Predictor") +
theme_classic(base_size = 24) +
theme(axis.text.x = element_text(angle = 45, vjust = 0.9, hjust=1))
-Gaps: silent time intervals between songs - Mean SPL has been mean-centered to facilitate interpretation
dat_gaps <- readRDS("./output/dat_song_spectrographic_consistency_and_gaps.RDS")
dat_gaps$mean.spl <- mean(dat_gaps$mean.spl) - dat_gaps$mean.spl
# model SPL by body size
gap_formulas <- c("mean.gaps ~ 1", "mean.gaps ~ treatment", "mean.gaps ~ treatment + mean.spl", "mean.gaps ~ treatment * mean.spl" , "mean.gaps ~ mean.spl")
gap_mods <- pblapply(gap_formulas, function(x){
replicate(n = 3, MCMCglmm(as.formula(x), random = ~ ID + songtype, data = dat_gaps, verbose = FALSE, nitt = itrns, start = list(QUASI = FALSE)), simplify = FALSE)
})
names(gap_mods) <- gsub("cal.spl ~ ", "", gap_formulas)
saveRDS(list(gap_formulas = gap_formulas, gap_mods = gap_mods), "./output/mcmcglmm_gap_models.RDS")
attach(readRDS("./output/mcmcglmm_gap_models.RDS"))
mod_list <- lapply(gap_mods, "[[", 1)
names(mod_list) <- gsub("cal.spl ~ ", "", gap_formulas)
model_selection <- model.sel(mod_list, rank="DIC")
model_selection
(Intercept) | treatment | mean.spl | mean.spl:treatment | family | df | logLik | DIC | delta | weight | |
---|---|---|---|---|---|---|---|---|---|---|
mean.gaps ~ treatment * mean.spl | 0.6678307 | + | -0.0092550 | + | (NA) | 7 | 25.85278 | -46.42077 | 0.000000 | 0.71994310 |
mean.gaps ~ treatment + mean.spl | 0.6729941 | + | -0.0048448 | NA | (NA) | 6 | 23.75377 | -43.12839 | 3.292379 | 0.13879285 |
mean.gaps ~ treatment | 0.6797477 | + | NA | NA | (NA) | 5 | 23.11416 | -42.36029 | 4.060472 | 0.09453179 |
mean.gaps ~ 1 | 0.7056103 | NA | NA | NA | (NA) | 4 | 21.21979 | -39.80056 | 6.620202 | 0.02628691 |
mean.gaps ~ mean.spl | 0.7053243 | NA | -0.0035014 | NA | (NA) | 5 | 21.25474 | -39.29793 | 7.122835 | 0.02044534 |
# summary
best_mod_gap <- gap_mods[[which(names(gap_mods) == row.names(model_selection)[1])]][[1]]
sm_gap <- as.data.frame(summary(best_mod_gap)$solutions[, -5])
sm_gap
post.mean | l-95% CI | u-95% CI | eff.samp | |
---|---|---|---|---|
(Intercept) | 0.6678307 | 0.6203597 | 0.7130255 | 9700.000 |
treatmentBefore | 0.0636878 | 0.0114525 | 0.1166435 | 9700.000 |
mean.spl | -0.0092550 | -0.0168684 | -0.0014809 | 9313.085 |
treatmentBefore:mean.spl | 0.0087411 | -0.0012228 | 0.0179838 | 10105.701 |
dat_gaps <- readRDS("./output/dat_song_spectrographic_consistency_and_gaps.RDS")
# subset data
dat_gaps$ID <- as.character(dat_gaps$ID)
ggplot(dat_gaps, aes(x = mean.gaps, y = xcrr)) +
geom_point(size = 4, color = viridis(5, alpha = 0.5)[3]) +
labs(y = "Mean gap duration (s)", x = "Sound pressure level (dB)") +
scale_color_viridis_d(begin = 0.1, end = 0.8, alpha = 0.7) +
theme_classic(base_size = 24)
Effect size posterior distribution
# stack posteriors
Y <- stack(as.data.frame(best_mod_gap$Sol[, -1]))
# plot posteriors
ggplot(Y, aes(y=values, x = ind)) +
geom_hline(yintercept = 0, col = "red", lty = 2) +
geom_violin(color = "gray40", fill = viridis(n = 1, alpha = 0.25, begin = 0.4)) +
labs(y = "Effect size posterior distribution",x = "Predictor") +
theme_classic(base_size = 24) +
theme(axis.text.x = element_text(angle = 45, vjust = 0.9, hjust=1))
# zoom in
Y <- stack(as.data.frame(best_mod_gap$Sol[, -c(1, 2)]))
ggplot(Y, aes(y=values, x = ind)) +
geom_hline(yintercept = 0, col = "red", lty = 2) +
geom_violin(color = "gray40", fill = viridis(n = 1, alpha = 0.25, begin = 0.4)) +
labs(y = "Effect size posterior distribution",x = "Predictor") +
theme_classic(base_size = 24) +
theme(axis.text.x = element_text(angle = 45, vjust = 0.9, hjust=1))
# extract mcmcs
mcmcs <- best_mod_gap$Sol
# make empty list
mcmc_l <- list()
## after interaction 0 spl
mcmc_l[[length(mcmc_l) + 1]] <- data.frame(spl = mcmcs[,"(Intercept)"], treatment = "After", type = "0 spl")
## before interaction 0 spl
mcmc_l[[length(mcmc_l) + 1]] <- data.frame(spl = mcmcs[,"(Intercept)"] + mcmcs[, "treatmentBefore"], treatment = "Before", type = "0 spl")
## before interaction 1 spl
mcmc_l[[length(mcmc_l) + 1]] <- data.frame(spl = mcmcs[,"(Intercept)"] + mcmcs[, "treatmentBefore"] + mcmcs[,"mean.spl"], treatment = "Before", type = "1 spl")
## after interaction 1 spl
mcmc_l[[length(mcmc_l) + 1]] <- data.frame(spl = mcmcs[,"(Intercept)"] + mcmcs[,"mean.spl"], treatment = "After", type = "1 spl")
mcmc_df <- do.call(rbind, mcmc_l)
colnames(mcmc_df)[1] <- "spl"
mcmc_df$treatment_type <- paste(mcmc_df$treatment, mcmc_df$type, sep = "-")
# p-values
combs <- combn(x = unique(mcmc_df$treatment_type), m = 2)
pvals_l <- lapply(1:ncol(combs), function(x){
mcmc1 <- mcmc_df$spl[mcmc_df$treatment_type == combs[1, x]]
mcmc2 <- mcmc_df$spl[mcmc_df$treatment_type == combs[2, x]]
p <- if (mean(mcmc2) > mean(mcmc1))
sum(mcmc1 > mcmc2) / length(mcmc1) else
sum(mcmc2 > mcmc1) / length(mcmc1)
out <- data.frame(mcmc1 = combs[1, x], mcmc2 = combs[2, x], p = p)
return(out)
})
pvals <- do.call(rbind, pvals_l)
mcmc_df$treatment <-factor(mcmc_df$treatment, levels = c("Before", "After"))
mcmc_df$type <-factor(mcmc_df$type, levels = c("Perch interaction", "Chase"))
# plot posteriors
ggplot(mcmc_df, aes(y=spl, x = treatment)) +
# geom_hline(yintercept = 0, col = "red", lty = 2) +
geom_violin(color = "gray40", fill = viridis(n = 1, alpha = 0.25, begin = 0.4)) +
labs(y = "SPL posterior distribution",x = "Predictor") +
theme_classic(base_size = 24) +
facet_wrap(~ type) +
theme(axis.text.x = element_text(angle = 45, vjust = 0.9, hjust=1))
kable(pvals)
Include Gelman/Rubin’s convergence diagnostic, MCMC chain trace (all tree replicates in a single plot: yellow, blue and red colors) and autocorrelation plots:
mcmc_diagnostics(period_mods)
## [1] "model: Null"
## [1] "model: period"
mcmc_diagnostics(size_mods)
## [1] "model: Null"
## [1] "model: PC1"
## [1] "model: lift.weight"
## [1] "model: lift.weight + PC1"
## [1] "model: lift.weight * PC1"
mcmc_diagnostics(inter_mods)
## [1] "model: Null"
## [1] "model: inter_treatment"
## [1] "model: inter_treatment + inter_type"
## [1] "model: inter_treatment * inter_type"
mcmc_diagnostics(song_consistency_mods)
## [1] "model: xcrr ~ 1"
## [1] "model: xcrr ~ treatment"
## [1] "model: xcrr ~ treatment + mean.spl"
## [1] "model: xcrr ~ treatment * mean.spl"
## [1] "model: xcrr ~mean.spl"
mcmc_diagnostics(gap_mods)
## [1] "model: mean.gaps ~ 1"
## [1] "model: mean.gaps ~ treatment"
## [1] "model: mean.gaps ~ treatment + mean.spl"
## [1] "model: mean.gaps ~ treatment * mean.spl"
## [1] "model: mean.gaps ~ mean.spl"
Session information
## R version 4.0.3 (2020-10-10)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04.1 LTS
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/liblapack.so.3
##
## locale:
## [1] LC_CTYPE=pt_PT.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=es_CR.UTF-8 LC_COLLATE=pt_PT.UTF-8
## [5] LC_MONETARY=es_CR.UTF-8 LC_MESSAGES=pt_PT.UTF-8
## [7] LC_PAPER=es_CR.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=es_CR.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] grid parallel stats graphics grDevices utils datasets
## [8] methods base
##
## other attached packages:
## [1] gridExtra_2.3 lme4_1.1-26 corrplot_0.84 MuMIn_1.43.17
## [5] MCMCglmm_2.32 ape_5.4-1 coda_0.19-4 Matrix_1.2-18
## [9] rptR_0.9.22 readxl_1.3.1 viridis_0.5.1 viridisLite_0.3.0
## [13] Rraven_1.0.12 warbleR_1.1.27 NatureSounds_1.0.3 knitr_1.31
## [17] seewave_2.1.6 tuneR_1.3.3 ggplot2_3.3.3 pbapply_1.4-3
##
## loaded via a namespace (and not attached):
## [1] Rcpp_1.0.6 lattice_0.20-41 corpcor_1.6.9 fftw_1.0-6
## [5] digest_0.6.27 R6_2.5.0 cellranger_1.1.0 signal_0.7-6
## [9] stats4_4.0.3 evaluate_0.14 highr_0.8 pillar_1.4.6
## [13] rlang_0.4.10 cubature_2.0.4.1 minqa_1.2.4 nloptr_1.2.2.2
## [17] rmarkdown_2.4 labeling_0.4.2 splines_4.0.3 statmod_1.4.35
## [21] stringr_1.4.0 RCurl_1.98-1.3 munsell_0.5.0 proxy_0.4-25
## [25] compiler_4.0.3 xfun_0.22 pkgconfig_2.0.3 htmltools_0.5.1.1
## [29] tidyselect_1.1.0 tibble_3.0.4 tensorA_0.36.2 dtw_1.22-3
## [33] crayon_1.4.1 dplyr_1.0.2 withr_2.4.1 MASS_7.3-53
## [37] bitops_1.0-6 nlme_3.1-149 gtable_0.3.0 lifecycle_0.2.0
## [41] magrittr_2.0.1 scales_1.1.1 stringi_1.5.3 farver_2.1.0
## [45] ellipsis_0.3.1 generics_0.1.0 vctrs_0.3.6 boot_1.3-25
## [49] rjson_0.2.20 tools_4.0.3 glue_1.4.2 purrr_0.3.4
## [53] yaml_2.2.1 colorspace_2.0-0