opts_knit$set(root.dir = "..")
opts_chunk$set(fig.width = 12, fig.height = 8)
theme_set(theme_classic(base_size = 34))
# print results brms models
summary_brm_model <- function(x, gsub.pattern = NULL, gsub.replacement = NULL, cols = viridis(10, alpha = 0.7)){
summ <- summary(x)$fixed
fit <- x$fit
betas <- grep("^b_", names(fit@sim$samples[[1]]), value = TRUE)
hdis <- t(sapply(betas, function(y) hdi(fit@sim$samples[[1]][[y]]))
)
summ_table <- data.frame(summ, hdis, iterations = attr(fit, "stan_args")[[1]]$iter, chains = length(attr(fit, "stan_args")))
summ_table <- summ_table[rownames(summ_table) != "Intercept", c("Estimate", "Rhat", "Bulk_ESS", "l.95..CI", "u.95..CI", "iterations", "chains")]
summ_table <- as.data.frame(summ_table)
summ_table$Rhat <- round(summ_table$Rhat, digits = 3)
summ_table$CI_low <- round(unlist(summ_table$l.95..CI), digits = 3)
summ_table$CI_high <- round(unlist(summ_table$u.95..CI), digits = 3)
summ_table$l.95..CI <- summ_table$u.95..CI <- NULL
out <- lapply(betas, function(y) data.frame(variable = y, value = sort(fit@sim$samples[[1]][[y]], decreasing = FALSE)))
posteriors <- do.call(rbind, out)
posteriors <- posteriors[posteriors$variable != "b_Intercept", ]
if (!is.null(gsub.pattern) & !is.null(gsub.replacement))
posteriors$variable <- gsub(pattern = gsub.pattern, replacement = gsub.replacement, posteriors$variable)
gg <- ggplot(data = posteriors, aes(y = variable, x = value, fill = stat(quantile))) +
geom_density_ridges_gradient(quantile_lines = TRUE, quantile_fun = HDInterval::hdi, vline_linetype = 2) +
theme_classic() +
xlim(range(c(min(summ_table[ , "CI_low"]), max(summ_table[ , "CI_high"])), 0)) +
geom_vline(xintercept = 0, col = "red") +
scale_fill_manual(values = c("transparent", "lightblue", "transparent"), guide = "none") + ggtitle(x$formula)
if (!is.null(gsub.pattern) & !is.null(gsub.replacement))
rownames(summ_table) <- gsub(pattern = gsub.pattern, replacement = gsub.replacement, rownames(summ_table))
summ_table$Rhat <- ifelse(summ_table$Rhat > 1.05, cell_spec(summ_table$Rhat, "html", color ="white", background = "red", bold = TRUE, font_size = 12), cell_spec(summ_table$Rhat, "html"))
signif <- summ_table[,"CI_low"] * summ_table[,"CI_high"] > 0
df1 <- kbl(summ_table, row.names = TRUE, escape = FALSE, format = "html", digits = 3)
df1 <- row_spec(kable_input = df1,row = which(summ_table$CI_low * summ_table$CI_high > 0), background = adjustcolor(cols[9], alpha.f = 0.3))
df1 <- kable_styling(df1, bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE, font_size = 12)
print(df1)
print(gg)
}
dat <- as.data.frame(read_excel(path = "./data/raw/Anexo 1_Entrada a refugios-2022.xlsx"))
dat$entry.time <- as.numeric(dat$`Tiempo real`)
## Warning: NAs introduzidos por coerção
# dat$entry.time
#
# str(dat)
cat("Number of individuals per type:")
## Number of individuals per type:
(table(dat$`Tipo grupo`))
##
## Individual Mixto Real
## 35 118 159
cat("Number of individuals per type removing missing data (NAs and Inf:")
## Number of individuals per type removing missing data (NAs and Inf:
(table(dat$`Tipo grupo`[!is.infinite(dat$entry.time) & !is.na(dat$entry.time)]))
##
## Individual Mixto Real
## 17 65 95
group_dat <- dat[!is.infinite(dat$entry.time) & !is.na(dat$entry.time) & dat$`Tipo grupo` != "Individual", ]
# get difference to first entry
group_dat_l <- lapply(unique(group_dat$Grupo), function(x){
# print(x)
X <- group_dat[group_dat$Grupo == x, ]
X$entry.time.diff <- X$entry.time - min(X$entry.time)
X <- X[-which.min(X$entry.time.diff), ]
X$group.size <- if (nrow(X) > 0) nrow(X) - 1 else vector()
return(X)
})
group_dat <- do.call(rbind, group_dat_l)
group_dat$Group <- group_dat$Grupo
group_dat$entry.time.diff[group_dat$entry.time.diff == 0] <- 0.001
group_dat$type <- factor(ifelse(group_dat$`Tipo grupo` == "Mixto", "Aritficial", "Real"), levels = c("Aritficial", "Real"))
# individual plot solo vs individual in group
ggplot(group_dat, aes(x = type, y = log(entry.time.diff))) +
geom_boxplot() +
# geom_point(size = 2) +
# scale_color_viridis_c(alpha = 0.8) +
labs(x = "Group type", y = "log(time after first entry (s))") +
# facet_grid( ~ experiment_f) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
chains <- 1
iter <- 5000
model_formulas <- c("entry.time.diff ~ type + (1 | Group) + (1 | group.size)", "entry.time.diff ~ 1 + (1 | Group) + (1 | group.size)")
brms_models <- lapply(model_formulas, function(x){
mod <- brm(
formula = x,
iter = iter,
thin = 1,
data = group_dat,
family = lognormal(),
silent = 2,
chains = chains,
cores = chains
)
mod <- add_criterion(mod, c("loo"))
return(mod)
})
names(brms_models) <- model_formulas
saveRDS(brms_models, "./data/processed/roost_entry_coordination_models.RDS")
brms_models <- readRDS("./data/processed/roost_entry_coordination_models.RDS")
cat(paste(length(brms_models),"models evaluated:\n"))
2 models evaluated:
for(i in names(brms_models))
cat(paste("- ", i, "\n"))
comp_mods <- loo_compare(brms_models[[1]], brms_models[[2]], model_names = names(brms_models))
df1 <- kbl(comp_mods, row.names = TRUE, escape = FALSE, format = "html", digits = 3)
cat("Compare models:")
Compare models:
kable_styling(df1, bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE, font_size = 12)
elpd_diff | se_diff | elpd_loo | se_elpd_loo | p_loo | se_p_loo | looic | se_looic | |
---|---|---|---|---|---|---|---|---|
entry.time.diff ~ 1 + (1 | Group) + (1 | group.size) | 0.000 | 0.000 | -453.128 | 27.109 | 20.834 | 3.708 | 906.256 | 54.217 |
entry.time.diff ~ type + (1 | Group) + (1 | group.size) | -0.781 | 2.253 | -453.909 | 26.927 | 18.435 | 3.646 | 907.818 | 53.853 |
cat("Best model:\n")
Best model:
cat(paste("- ", rownames(comp_mods)[1], "\n"))
# best model
if (!grepl("1 +", rownames(comp_mods)[1], fixed = TRUE))
summary_brm_model(brms_models[[rownames(comp_mods)[1]]], gsub.pattern = "experiment.type", gsub.replacement = "solo_vs_")
group_dat <- dat[!is.infinite(dat$entry.time) & !is.na(dat$entry.time) & dat$`Tipo grupo` != "Individual", ]
# get difference to first entry
group_dat_l <- lapply(unique(group_dat$Grupo), function(x){
# print(x)
X <- group_dat[group_dat$Grupo == x, ]
X$entry.time.diff <- X$entry.time - min(X$entry.time)
X <- X[-which.min(X$entry.time.diff), ]
X$group.size <- if (nrow(X) > 0) nrow(X) + 1 else vector()
return(X)
})
group_dat <- do.call(rbind, group_dat_l)
group_dat$Group <- group_dat$Grupo
group_dat$entry.time.diff[group_dat$entry.time.diff == 0] <- 0.001
group_dat$type <- factor(ifelse(group_dat$`Tipo grupo` == "Mixto", "Artificial", "Real"), levels = c("Simulated", "Artificial", "Real"))
# make random groups from individual flights
indiv_dat <- dat[!is.infinite(dat$entry.time) & !is.na(dat$entry.time) & dat$`Tipo grupo` == "Individual", ]
indivs <- unique(indiv_dat$Individuo)
sim_groups_l <- pblapply(1:1000, function(x){
g_size <- sample(group_dat$group.size)
n_group <- sum(cumsum(g_size) <= length(indivs))
g_size <- g_size[1:n_group]
sampled_indivs <- sample(indivs, sum(g_size))
indivs_split <- split(sampled_indivs, f = unlist(sapply(1:n_group, function(x) rep(x, g_size[x]))))
sub_sim_groups_l <- lapply(1:length(indivs_split), function(y) {
sim_group <- indiv_dat[indiv_dat$Individuo %in% indivs_split[[y]], ]
sim_group$Group <- paste("sim",x, y, sep = "-")
sim_group$entry.time.diff <- sim_group$entry.time - min(sim_group$entry.time)
sim_group <- sim_group[-which.min(sim_group$entry.time.diff), ]
sim_group$group.size <- nrow(sim_group) + 1
sim_group$type <- factor("Simulated")
out <- rbind(sim_group, group_dat)
return(out)
}
)
sub_sim_group <- do.call(rbind, sub_sim_groups_l)
return(sub_sim_group)
})
sim_group_n <- sapply(sim_groups_l, function(x) length(unique(x$Group[x$type == "Simulated"])))
table(sim_group_n)
# keep those with same number of simulated groups
sim_groups_l <- sim_groups_l[which(sim_group_n == 5)]
sim_groups_l <- lapply(sim_groups_l, function(x){
Y <- x[x$type == "Simulated", ]
Y$Group <- as.numeric(as.factor(Y$Group))
Y <- rbind(Y, x[x$type != "Simulated", ])
return(Y)
})
# keep only 30
sim_groups_l <- sim_groups_l[1:30]
sim_group_dat <- do.call(rbind, lapply(sim_groups_l, function(x) x[x$type == "Simulated", ]))
sim_group_dat <- rbind(sim_group_dat, group_dat)
# individual plot solo vs individual in group
ggplot(sim_group_dat, aes(x = type, y = log(entry.time.diff))) +
geom_boxplot() +
# geom_point(size = 2) +
# scale_color_viridis_c(alpha = 0.8) +
labs(x = "Flight", y = "log(time after first entry (s))") +
# facet_grid( ~ experiment_f) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
saveRDS(sim_groups_l, "./data/processed/simulated_data_entry_time.RDS")
sim_groups_l <- readRDS("./data/processed/simulated_data_entry_time.RDS")
chains <- 1
iter <- 10000
mods <- brm_multiple(
formula = entry.time.diff ~ type + (1 | Group) + (1 | group.size),
iter = iter,
thin = 1,
data = sim_groups_l,
family = lognormal(),
silent = 2,
chains = chains,
cores = chains,
combine = FALSE
)
combined_mod <- combine_models(mlist = mods, check_data = FALSE)
saveRDS(combined_mod, "./data/processed/simulated_data_entry_time_models.RDS")
combined_mod <- readRDS("./data/processed/simulated_data_entry_time_models.RDS")
summary_brm_model(combined_mod)
## Warning: There were 816 divergent transitions after warmup. Increasing
## adapt_delta above 0.8 may help. See http://mc-stan.org/misc/
## warnings.html#divergent-transitions-after-warmup
Estimate | Rhat | Bulk_ESS | iterations | chains | CI_low | CI_high | |
---|---|---|---|---|---|---|---|
typeArtificial | -3.221 | 1.018 | 28996.700 | 10000 | 30 | -5.884 | -0.609 |
typeReal | -4.524 | 1.027 | 1265.216 | 10000 | 30 | -6.752 | -2.251 |
## Picking joint bandwidth of 0.166
Real vs artificial:
contrasts <- c(real_vs_artificial = "typeReal - typeArtificial = 0")
hypothesis(combined_mod, contrasts)
## Hypothesis Tests for class b:
## Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio Post.Prob
## 1 real_vs_artificial -1.3 0.92 -3.09 0.49 NA NA
## Star
## 1
## ---
## 'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
## '*': For one-sided hypotheses, the posterior probability exceeds 95%;
## for two-sided hypotheses, the value tested against lies outside the 95%-CI.
## Posterior probabilities of point hypotheses assume equal prior probabilities.
group_dat <- dat[dat$`Tipo grupo` != "Individual", ]
group_dat$indiv.entry <- ifelse(is.na(group_dat$entry.time) | is.infinite(group_dat$entry.time), 0, 1)
group_dat$Group <- group_dat$Grupo
group_dat$type <- factor(ifelse(group_dat$`Tipo grupo` == "Mixto", "Aritficial", "Real"), levels = c("Aritficial", "Real"))
agg_dat <- aggregate(indiv.entry ~ Group + type, group_dat, FUN = sum)
agg_dat$group.size <- aggregate(indiv.entry ~ Group + type, group_dat, FUN = length)$indiv.entry
agg_dat$entry <- "Partial"
agg_dat$entry[agg_dat$group.size == agg_dat$indiv.entry] <- "Full"
agg_dat$entry[agg_dat$indiv.entry == 0] <- "None"
count_dat <- aggregate(Group ~ entry + type, agg_dat, length)
count_dat$entry <- factor(count_dat$entry, levels = c("None", "Partial", "Full"))
# Change barplot fill colors by groups
ggplot(count_dat, aes(x=entry, y=Group, fill=type)) +
geom_bar(stat="identity", position=position_dodge()) +
scale_fill_viridis_d(begin = 0.3, end = 0.8) +
theme_classic()
# mean centering
agg_dat$group.size <- agg_dat$group.size - mean(agg_dat$group.size)
chains <- 1
iter <- 10000
agg_dat$entry[agg_dat$entry == "None"] <- "1_None"
model_formulas <- c("entry ~ type + (1 | Group) + ( 1 | group.size)")
brms_models <- lapply(model_formulas, function(x){
print(x)
mod <- brm(data = agg_dat,
family = categorical,
formula = x,
iter = iter,
chains = chains,
cores = chains
)
try(mod <- add_criterion(mod, c("loo")))
return(mod)
})
names(brms_models) <- model_formulas
saveRDS(brms_models, "./data/processed/roost_entry_models.RDS")
brms_models <- readRDS("./data/processed/roost_entry_models.RDS")
summary_brm_model(brms_models$`entry ~ type + (1 | Group) + ( 1 | group.size)`)
## Warning: There were 2 divergent transitions after warmup. Increasing adapt_delta
## above 0.8 may help. See http://mc-stan.org/misc/warnings.html#divergent-
## transitions-after-warmup
Estimate | Rhat | Bulk_ESS | iterations | chains | CI_low | CI_high | |
---|---|---|---|---|---|---|---|
muFull_Intercept | -0.693 | 1 | 560.074 | 10000 | 1 | -16.059 | 5.511 |
muPartial_Intercept | 6.370 | 1 | 1342.146 | 10000 | 1 | 1.466 | 17.166 |
muFull_typeReal | 2.479 | 1.001 | 577.631 | 10000 | 1 | -5.492 | 27.256 |
muPartial_typeReal | -12.342 | 1 | 1103.571 | 10000 | 1 | -32.277 | -3.617 |
## Picking joint bandwidth of 0.525
contrasts <- c(one = "muFull_Intercept - muFull_typeReal = 0")
hypothesis(brms_models$`entry ~ type + (1 | Group) + ( 1 | group.size)`, contrasts)
## Hypothesis Tests for class b:
## Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio Post.Prob Star
## 1 one -3.17 12.28 -42.72 10.63 NA NA
## ---
## 'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
## '*': For one-sided hypotheses, the posterior probability exceeds 95%;
## for two-sided hypotheses, the value tested against lies outside the 95%-CI.
## Posterior probabilities of point hypotheses assume equal prior probabilities.
brms_models <- readRDS("./data/processed/roost_entry_models.RDS")
cat(paste(length(brms_models),"models evaluated:\n"))
for(i in names(brms_models))
cat(paste("- ", i, "\n"))
comp_mods <- loo_compare(brms_models[[1]], brms_models[[2]], brms_models[[3]], model_names = names(brms_models))
df1 <- kbl(comp_mods, row.names = TRUE, escape = FALSE, format = "html", digits = 3)
cat("Compare models:")
kable_styling(df1, bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE, font_size = 12)
cat("Best model:\n")
cat(paste("- ", rownames(comp_mods)[1], "\n"))
# best model
if (!grepl("1 +", rownames(comp_mods)[1], fixed = TRUE))
summary_brm_model(brms_models[[rownames(comp_mods)[1]]], gsub.pattern = "experiment.type", gsub.replacement = "solo_vs_")
Full entry of real vs artificial groups:
real_distances_l <- readRDS("./data/processed/real_trajectory_mean_distances.RDS")
Session information
## R version 4.1.0 (2021-05-18)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04.2 LTS
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/atlas/libblas.so.3.10.3
## LAPACK: /usr/lib/x86_64-linux-gnu/atlas/liblapack.so.3.10.3
##
## locale:
## [1] LC_CTYPE=pt_BR.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=es_CR.UTF-8 LC_COLLATE=pt_BR.UTF-8
## [5] LC_MONETARY=es_CR.UTF-8 LC_MESSAGES=pt_BR.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] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] tidybayes_3.0.1 ggridges_0.5.3 kableExtra_1.3.1 brms_2.16.3
## [5] Rcpp_1.0.8.3 pbapply_1.5-0 readxl_1.3.1 knitr_1.37
## [9] ggplot2_3.3.5 viridis_0.6.2 viridisLite_0.4.0
##
## loaded via a namespace (and not attached):
## [1] minqa_1.2.4 colorspace_2.0-2 ellipsis_0.3.2
## [4] rsconnect_0.8.18 markdown_1.1 base64enc_0.1-3
## [7] rstudioapi_0.13 farver_2.1.0 rstan_2.21.2
## [10] svUnit_1.0.6 DT_0.18 fansi_1.0.0
## [13] mvtnorm_1.1-2 diffobj_0.3.4 xml2_1.3.2
## [16] bridgesampling_1.1-2 codetools_0.2-18 splines_4.1.0
## [19] shinythemes_1.2.0 bayesplot_1.8.1 projpred_2.0.2
## [22] jsonlite_1.7.2 nloptr_1.2.2.2 ggdist_3.0.0
## [25] shiny_1.6.0 httr_1.4.2 compiler_4.1.0
## [28] backports_1.3.0 assertthat_0.2.1 Matrix_1.3-4
## [31] fastmap_1.1.0 cli_3.1.0 later_1.2.0
## [34] htmltools_0.5.2 prettyunits_1.1.1 tools_4.1.0
## [37] igraph_1.2.6 coda_0.19-4 gtable_0.3.0
## [40] glue_1.6.2 reshape2_1.4.4 dplyr_1.0.7
## [43] posterior_1.1.0 V8_3.4.2 cellranger_1.1.0
## [46] jquerylib_0.1.4 vctrs_0.3.8 nlme_3.1-152
## [49] crosstalk_1.1.1 tensorA_0.36.2 xfun_0.30
## [52] stringr_1.4.0 ps_1.6.0 rvest_1.0.0
## [55] lme4_1.1-27.1 mime_0.11 miniUI_0.1.1.1
## [58] lifecycle_1.0.1 gtools_3.9.2 MASS_7.3-54
## [61] zoo_1.8-9 scales_1.1.1 colourpicker_1.1.0
## [64] promises_1.2.0.1 Brobdingnag_1.2-6 parallel_4.1.0
## [67] inline_0.3.19 shinystan_2.5.0 gamm4_0.2-6
## [70] yaml_2.3.5 curl_4.3.2 gridExtra_2.3
## [73] loo_2.4.1.9000 StanHeaders_2.21.0-7 sass_0.4.0
## [76] stringi_1.7.6 highr_0.9 dygraphs_1.1.1.6
## [79] checkmate_2.0.0 boot_1.3-28 pkgbuild_1.2.0
## [82] rlang_1.0.1 pkgconfig_2.0.3 matrixStats_0.61.0
## [85] HDInterval_0.2.2 distributional_0.2.2 evaluate_0.15
## [88] lattice_0.20-44 purrr_0.3.4 labeling_0.4.2
## [91] rstantools_2.1.1 htmlwidgets_1.5.3 tidyselect_1.1.1
## [94] processx_3.5.2 plyr_1.8.6 magrittr_2.0.2
## [97] R6_2.5.1 generics_0.1.0 DBI_1.1.1
## [100] mgcv_1.8-36 pillar_1.6.4 withr_2.4.3
## [103] xts_0.12.1 abind_1.4-5 tibble_3.1.6
## [106] crayon_1.5.0 arrayhelpers_1.1-0 utf8_1.2.2
## [109] rmarkdown_2.9 grid_4.1.0 callr_3.7.0
## [112] threejs_0.3.3 webshot_0.5.2 digest_0.6.29
## [115] xtable_1.8-4 tidyr_1.1.3 httpuv_1.6.1
## [118] RcppParallel_5.1.4 stats4_4.1.0 munsell_0.5.0
## [121] bslib_0.2.5.1 shinyjs_2.0.0