library(SIBER)
library(ggplot2)
library(ggExtra)
library(ggConvexHull)
library(HDInterval)
library(mcmcplots)
library(ggmcmc)
library(coda)
library(lattice)
library(MCMCvis)
library(bayesplot)
3 Amplitudes and comparisons of the isotopic niches
3.1 Libraries
3.2 Data loading
<- read.table("data/glm.csv", sep = ",", header = T)
data colnames(data)[6:7] <- c("iso1", "iso2")
3.3 “Global” SIBER:
3.3.1 Dataset arrangement
<- subset(data, select = c(sp, iso1, iso2))
global $group <- factor(global$sp, labels = c(1:3))
global$community <- 1
global global
3.3.2 Basic plot
Parameters and basic information
<- c('#1f77b4', '#ff7f0e', '#2ca02c')
global_colors <- c(min(global$iso2)-0.5, max(global$iso2)+0.5)
xlims <- c(min(global$iso1)-0.5, max(global$iso1)+0.5)
ylims <- unique(global$sp) species
Plot
<- ggplot(data = global, aes(x = iso2, y = iso1, color = as.factor(group))) +
glob_ellipses geom_point(alpha = 0.7) +
stat_ellipse(level = 0.4) +
geom_convexhull(fill = NA, linetype = "dashed", alpha = 0.05) +
scale_color_manual(values = global_colors, name = "Species", labels = species) +
scale_x_continuous(limits = xlims, breaks = c(seq(-18, -8, 2))) +
scale_y_continuous(limits = ylims, breaks = c(seq(10, 20, 2))) +
labs(title = element_blank(),
x = expression({delta}^13*C~'(\u2030)'),
y = expression({delta}^15*N~'(\u2030)')) +
theme_bw() +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.20, 0.17),
legend.background = element_blank())
# cairo_pdf("output/SIBER/global/global_ellipses.pdf",
# family = "Times", height = 3.5, width = 3.5)
glob_ellipses
# dev.off()
3.3.3 Fitting the Bayesian Bi-variate Normal models:
Creation of the SIBER object:
<- createSiberObject(global[,2:5]) siber_glob
Parameters of the MCMC:
<- list()
parms $n.iter <- 20000
parms$n.burnin <- 25000
parms$n.thin <- 1
parms$n.chains <- 3
parms$save.output <- TRUE
parms$save.dir <- paste(getwd(),"/output/SIBER/global", sep = "") parms
Prior distributions:
<- list()
priors $R <- 1 * diag(2)
priors$k <- 2
priors$tau.mu <- 1.0E-3 priors
Sampling of the posterior distributions:
<- siberMVN(siber_glob, parms, priors) ellipses.posterior
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 81
Unobserved stochastic nodes: 3
Total graph size: 96
Initializing model
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 69
Unobserved stochastic nodes: 3
Total graph size: 84
Initializing model
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 74
Unobserved stochastic nodes: 3
Total graph size: 89
Initializing model
3.3.3.1 Diagnostics:
Cycling through every model to extract information:
<- dir(parms$save.dir, full.names = T)
all_files <- all_files[grep("jags_output", all_files)]
model_files
<- list()
model_summary
for (i in seq_along(model_files)) {
load(model_files[i])
<- coda::as.mcmc(do.call("cbind", output))
mcmc_list
<- MCMCsummary(output,
model_summary[[i]] params = "all",
probs = c(0.025, 0.975),
round = 3)
MCMCtrace(output,
params = "all",
iter = parms$n.iter,
Rhat = T,
n.eff = T,
ind = T,
type = "density",
open_pdf = F,
filename = sprintf("output/SIBER/global/MCMCtrace_%d", i))
}
Autocorrelation plots:
# cairo_pdf("output/SIBER/global_autocorr.pdf",
# family = "Times", height = 10, width = 12)
::grid.arrange(mcmc_acf(ellipses.posterior[1]) + labs(title = species[1]),
gridExtramcmc_acf(ellipses.posterior[2]) + labs(title = species[2]),
mcmc_acf(ellipses.posterior[3]) + labs(title = species[3]),
nrow = 3)
#dev.off()
Summaries. Gelman-Rubick Statistics (Rhat) exactly equal to 1 and effective sample sizes > 2000 for every parameter:
for (i in seq_along(model_files)) {
load(model_files[i])
print(species[i])
print(model_summary[[i]])
}
[1] "H.dipterurus"
mean sd 2.5% 97.5% Rhat n.eff
Sigma2[1,1] 1.025 0.165 0.751 1.393 1 60000
Sigma2[2,1] -0.557 0.132 -0.851 -0.331 1 59779
Sigma2[1,2] -0.557 0.132 -0.851 -0.331 1 59779
Sigma2[2,2] 1.025 0.165 0.753 1.392 1 58288
mu[1] 0.000 0.112 -0.221 0.220 1 31856
mu[2] 0.000 0.112 -0.220 0.221 1 31680
[1] "N.entemedor"
mean sd 2.5% 97.5% Rhat n.eff
Sigma2[1,1] 1.030 0.180 0.734 1.434 1 58420
Sigma2[2,1] -0.684 0.152 -1.025 -0.432 1 58657
Sigma2[1,2] -0.684 0.152 -1.025 -0.432 1 58657
Sigma2[2,2] 1.030 0.180 0.736 1.440 1 58409
mu[1] 0.001 0.121 -0.240 0.239 1 23172
mu[2] -0.001 0.122 -0.240 0.238 1 23062
[1] "R.steindachneri"
mean sd 2.5% 97.5% Rhat n.eff
Sigma2[1,1] 1.028 0.174 0.743 1.420 1 59100
Sigma2[2,1] -0.773 0.154 -1.119 -0.519 1 58438
Sigma2[1,2] -0.773 0.154 -1.119 -0.519 1 58438
Sigma2[2,2] 1.029 0.174 0.742 1.426 1 57750
mu[1] -0.002 0.118 -0.234 0.229 1 16294
mu[2] 0.002 0.118 -0.228 0.234 1 16515
3.3.3.2 Inferences
Generation of the ellipses:
<- siberEllipses(ellipses.posterior)
sea_b summary(sea_b)
V1 V2 V3
Min. : 6.193 Min. :1.323 Min. :1.077
1st Qu.: 8.875 1st Qu.:1.971 1st Qu.:1.541
Median : 9.555 Median :2.136 Median :1.666
Mean : 9.636 Mean :2.156 Mean :1.681
3rd Qu.:10.311 3rd Qu.:2.318 3rd Qu.:1.804
Max. :15.689 Max. :3.721 Max. :3.167
Graphical comparisons. First, transform the object to a data.frame and melt it to long format:
<- reshape2::melt(as.data.frame(sea_b)) sea_bt
No id variables; using all as measure variables
colnames(sea_bt) <- c("sp", "SEAb")
head(sea_bt)
Get the HDI for each species:
<- as.data.frame(t(apply(sea_b, 2, FUN = HDInterval::hdi)))
hdi <- cbind(hdi, means = t(as.data.frame(t(apply(sea_b, 2, FUN = mean)))))
hdi "sp"] <- row.names(hdi)
hdi[ hdi
Violin plot with the posterior distributions of the SEAb:
<- ggplot() +
seab_global geom_violin(data = sea_bt, aes(x = sp, y = SEAb, fill = sp, color = sp),
show.legend = F, alpha = 0.3) +
geom_boxplot(data = sea_bt,
aes(x = sp, y = SEAb, fill = sp, color = sp),
alpha = 0.5, width = 0.05, notch = T, show.legend = F,
outlier.shape = NA, coef = 0) +
scale_fill_manual(values = global_colors) +
scale_color_manual(values = global_colors) +
geom_linerange(data = hdi,
aes(x = sp, ymin = lower, ymax = upper, color = sp),
show.legend = F) +
theme_bw()+
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.2, 0.15),
legend.background = element_blank()) +
labs(x = "Species",
y = expression("SEAb " ('\u2030' ^2) )) +
scale_x_discrete(labels = species)
# cairo_pdf("output/SIBER/global/global_seab.pdf",
# family = "Times", height = 3.5, width = 3.5)
seab_global
#dev.off()
Posterior Differences:
# Define the comparisons
<- expand.grid(a = unique(as.integer(global$group)),
comps b = unique(as.integer(global$group)))
<- comps[(comps$a != comps$b & comps$b > comps$a), ]
comps <- comps[order(comps$a),]
comps
# Put the results in different objects:
<- data.frame()
diffs <- data.frame()
diff_glob <- data.frame()
p_sup for (i in seq_along(comps$a)) {
<- comps$a[i]
a <- comps$b[i]
b <- paste(species[a], "-", species[b])
comp <- sea_b[, a] - sea_b[, b]
diff <- subset(diff, diff>0, select = diff)
sup
<- rbind(diffs,
diffs data.frame(comp = comp,
diff = diff))
<- rbind(diff_glob,
diff_glob data.frame(comp = comp,
mean = mean(diff),
IQr = t(HDInterval::hdi(diff, credMass = 0.5)),
hdi = t(HDInterval::hdi(diff, credMass = 0.95))
)
)<- rbind(p_sup,
p_sup data.frame(comp = comp,
p_sup = (length(sup)/length(diff))*100))
}
$comp <- factor(diff_glob$comp, ordered = T) diff_glob
HDIs of differences
"keys"] <- factor(c("HD-NE", "HD-RS", "NE-RS"), ordered = T)
diff_glob[ diff_glob
Probabilities of differences:
p_sup
Forestplot of the \(HDI_{95\%}\) of the differences
<- ggplot(data = diff_glob) +
global_forest geom_vline(xintercept = 0, linetype = "dashed", color = "#C9C8C8", size = 1.2) +
geom_linerange(aes(y = factor(comp, ordered = T),
xmin = IQr.lower, xmax = IQr.upper),
color = global_colors[1], size = 1) +
geom_linerange(aes(y = factor(comp, ordered = T),
xmin = hdi.lower, xmax = hdi.upper),
color = global_colors[1]) +
geom_point(aes(x = mean, y = factor(comp, ordered = T)),
color = global_colors[1],
fill = "white", size = 1.5, shape = 21) +
theme_bw() +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.2, 0.15),
legend.background = element_blank()) +
labs(title = expression("Differences in SEAB " ('\u2030' ^2)),
x = element_blank(),
y = element_blank())
# cairo_pdf("output/SIBER/global/global_forest.pdf",
# family = "Times", height = 4, width = 4)
global_forest
# dev.off()
3.3.3.3 Eccentricity and theta
Eccentricities represent the elongation of the ellipse, that is, how far they are from a perfect circle (0 eccentricity). Lower values indicate a rounder ellipse, while higher values indicate a more elongated ellipse.
<- function(x) {
mat_ecc <- matrix(x, 2, 2)
mat <- sigmaSEA(mat)$ecc
ecc return(ecc)
}
<- function(x){
mat_theta <- matrix(x, 2, 2)
mat <- sigmaSEA(mat)$theta
theta return(theta)
}
<- data.frame()
ecc for (sp in seq_along(ellipses.posterior)) {
<- rbind(ecc,
ecc data.frame(sp = species[sp],
ecc = apply(ellipses.posterior[[sp]][,1:4], 1, mat_ecc),
theta = apply(ellipses.posterior[[sp]][,1:4], 1, mat_theta)))
}
<- ecc %>% group_by(sp) %>% summarise(IQR.lower = hdi(ecc, credMass = 0.5)[1],
ec IQR.upper = hdi(ecc, credMass = 0.5)[2],
hdi.lower = hdi(ecc)[1],
hdi.upper = hdi(ecc)[2],
mean = mean(ecc))
ec
ggplot(data = ecc, aes(x = sp, y = ecc, group = sp, color = factor(sp))) +
geom_violin(fill = NA, show.legend = F) +
geom_point(aes(x = sp, y = mean), data = ec, show.legend = F) +
#geom_errorbar(aes(x = sp, ymin = IQ.lower, ymax = IQ.upper, group = sp), data = ag) +
geom_boxplot(width = 0.1, show.legend = F) +
theme_bw() +
labs(title = "SEAB Eccentricity",
x = element_blank(),
y = element_blank()) +
scale_color_manual(values = global_colors) +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.15, 0.1),
legend.background = element_blank())
Theta, on the other hand, is the angle of the semi-major axis of the SEA and the x axis; i.e., the angle of the deformation. Values close to 0 show a higher dispersion in \(\delta^{13}C\), while values close to 90 show a higher dispersion in \(\delta^{15}N\):
<- ecc %>% group_by(sp) %>% summarise(IQR.lower = hdi(theta, credMass = 0.5)[1],
th IQR.upper = hdi(theta, credMass = 0.5)[2],
hdi.lower = hdi(theta)[1],
hdi.upper = hdi(theta)[2],
mean = mean(theta))
th
ggplot(data = ecc, aes(x = sp, y = theta, group = sp, color = factor(sp))) +
geom_violin(fill = NA, show.legend = F) +
geom_point(aes(x = sp, y = mean), data = ec, show.legend = F) +
#geom_errorbar(aes(x = sp, ymin = IQ.lower, ymax = IQ.upper, group = sp), data = ag) +
geom_boxplot(width = 0.1, show.legend = F) +
theme_bw() +
labs(title = "SEAB theta",
x = element_blank(),
y = element_blank()) +
scale_color_manual(values = global_colors) +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.15, 0.1),
legend.background = element_blank())
3.4 Intra-specific analyses
Basic dataset to extract every case:
<- subset(data,
full_set select = c(sp, temporada, sexo, estadio, iso1, iso2))
colnames(full_set) <- c("Species", "Season", "Sex", "Maturity", "iso1", "iso2")
head(full_set)
3.4.1 Custom wrapper around SIBER:
<- function(data, var_col, lbls, sp_col, colors, gp_label,
custom_siber n.burnin = 30000, n.iter = 2000){
<- data[,c(sp_col, var_col, "iso1", "iso2")]
subdata $group <- factor(subdata[,var_col], labels = seq_along(lbls))
subdata$community <- 1
subdata
<- unique(data[, sp_col])
species
# Global directory for the variable
<- paste(getwd(), "/output/SIBER/", var_col, sep = "")
wd
# If the directory does not exist, create it:
if (dir.exists(wd) == F) {dir.create(wd)}
# Empty lists to store the results:
<- list()
siber_objs <- list()
ellipses
<- list()
summaries <- list()
autocorr_plots
<- list()
sea_b <- data.frame()
sea_bt <- data.frame()
hdis <- data.frame()
ecc
# Posterior differences
# Define the comparisons
<- expand.grid(a = unique(as.integer(subdata$group)),
comps b = unique(as.integer(subdata$group)))
<- comps[(comps$a != comps$b & comps$b > comps$a), ]
comps <- comps[order(comps$a),]
comps
# Put the results in different objects:
<- data.frame()
diffs <- data.frame()
diff_glob <- data.frame()
p_sup
# List with MCMC parameters:
<- list()
parms <- list()
parms $n.iter <- n.iter
parms$n.burnin <- n.burnin
parms$n.thin <- 1
parms$n.chains <- 3
parms$save.output <- TRUE
parms
# List with prior parameters:
<- list()
priors $R <- 1 * diag(2)
priors$k <- 2
priors$tau.mu <- 1.0E-3
priors
# Basic ellipses plot
<- ggplot(data = subdata, aes(x = iso2, y = iso1, color = as.factor(group))) +
ellipses geom_point(alpha = 0.5) +
stat_ellipse(level = 0.4) +
geom_convexhull(fill = NA, linetype = "dashed", alpha = 0.05) +
scale_color_manual(values = global_colors, name = gp_label, labels = lbls) +
scale_x_continuous(limits = xlims, breaks = c(-18, -14, -10)) +
scale_y_continuous(limits = ylims, breaks = c(12, 16, 20)) +
labs(title = element_blank(),
x = expression({delta}^13*C~'(\u2030)'),
y = expression({delta}^15*N~'(\u2030)')) +
theme_bw() +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
#legend.position = c(0.2, 0.15),
legend.background = element_blank()) +
facet_wrap(paste("~", sp_col, sep = ""))
cairo_pdf(paste(wd, "ellipses.pdf", sep = "/"), family = "Times", height = 2.7, width = 5.4)
print(ellipses)
dev.off()
# Loop through species:
for (i in seq_along(species)) {
# Output directory:
<- paste(wd, "/", species[i], sep = "")
gpwd if (dir.exists(gpwd) == F) {dir.create(gpwd)}
$save.dir <- gpwd
parms
# SIBER objects
<- createSiberObject(subdata[subdata[, sp_col] == species[i],3:6])
siber_objs[[species[i]]]
# Fitting the Bayesian models:
<- siberMVN(siber_objs[[i]], parms, priors)
ellipses[[species[i]]]
# Diagnostics
## Get all the files in the directory
<- dir(parms$save.dir, full.names = T)
all_files <- all_files[grep("jags_output", all_files)]
model_files
# Empty lists to store the results
<- list()
summaries[[species[i]]] <- list()
autocorr_plots[[species[i]]]
# For each model:
for (j in seq_along(model_files)) {
# Load the model output
load(model_files[j])
# Create a list with the output
<- coda::as.mcmc(do.call("cbind", output))
mcmc_list
# Store the summary for each model
<- MCMCsummary(output,
summaries[[species[i]]][[j]]params = "all",
probs = c(0.025, 0.975),
round = 3)
# Write the summary to a csv file
write.csv(summaries[[species[i]]][[j]],
paste(gpwd, sprintf("summary_%s.csv",
sep = "/"),
lbls[j]), row.names = T)
# Plot the trace in a pdf
MCMCtrace(output,
params = "all",
iter = parms$n.iter,
Rhat = T,
n.eff = T,
ind = T,
type = "density",
open_pdf = F,
#filename = paste(gpwd, sprintf("/MCMCtrace_%d", j), sep = ""))
filename = sprintf("MCMCtrace_%s", lbls[j]),
wd = gpwd)
# Store the autocorrelation plots
<- mcmc_acf(ellipses[[species[i]]][j]) + labs(title = lbls[j])
autocorr_plots[[species[i]]][[j]]
# End of models loop
}
# Autocorrelation plots for every model for every species
cairo_pdf(paste(gpwd, "/autocorr.pdf", sep = ""), family = "Times")
::grid.arrange(grobs = autocorr_plots[[species[i]]], nrow = 2)
gridExtradev.off()
# Generation of the ellipses
<- siberEllipses(ellipses[[species[i]]])
sea_b[[species[i]]]
# Fill the data.frame with the SEAb data
<- rbind(sea_bt,
sea_bt cbind(reshape2::melt(as.data.frame(sea_b[[species[i]]])),
sp_col = species[i]))
if (i == max(seq_along(species))) {colnames(sea_bt) <- c(var_col, "SEAb", sp_col)}
# Create a data.frame to store the hdis
# Calculate posterior means
<- t(as.data.frame(t(apply(sea_b[[species[i]]], 2, FUN = mean))))
means # Calculate hdis
<- rbind(as.data.frame(t(apply(sea_b[[species[i]]], 2, FUN = HDInterval::hdi))))
hdi # Put the results in a data.frame
<- data.frame(hdi, means, sp = species[i])
temp
# Fill the data.frame with the results
<- rbind(hdis, temp)
hdis
if (i == max(seq_along(species))) {hdis[var_col] <- paste("V", rep(seq_along(model_files)), sep = "")}
# Compute the posterior SEAb differences
for (k in seq_along(comps$a)) {
<- comps$a[k]
a <- comps$b[k]
b <- paste(lbls[a], "-", lbls[b])
comp <- sea_b[[species[i]]][, a] - sea_b[[species[i]]][, b]
diff <- subset(diff, diff>0, select = diff)
sup
<- rbind(diffs,
diffs data.frame(comp = comp,
diff = diff,
sp = species[i]))
<- rbind(diff_glob,
diff_glob data.frame(comp = comp,
mean = mean(diff),
IQr = t(HDInterval::hdi(diff, credMass = 0.5)),
hdi = t(HDInterval::hdi(diff, credMass = 0.95)),
sp = species[i]
)
)<- rbind(p_sup,
p_sup data.frame(comp = comp,
p_sup = (length(sup)/length(diff))*100,
sp = species[i]))
}
$comp <- factor(diff_glob$comp, ordered = T)
diff_glob
# End of species loop
}
# Violin plot of SEAb
<- ggplot() +
seab geom_violin(data = sea_bt, aes_string(x = var_col, y = "SEAb", fill = var_col, color = var_col),
show.legend = F, alpha = 0.3) +
geom_boxplot(data = sea_bt,
aes_string(x = var_col, y = "SEAb", fill = var_col, color = var_col),
alpha = 0.5, width = 0.05, notch = T, show.legend = F,
outlier.shape = NA, coef = 0) +
scale_fill_manual(values = global_colors) +
scale_color_manual(values = global_colors) +
# geom_linerange(data = hdi,
# aes_string(x = var_col, ymin = "lower", ymax = "upper", color = var_col),
# show.legend = F) + # Fix needed
theme_bw() +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.2, 0.15),
legend.background = element_blank()) +
labs(x = gp_label,
y = expression("SEAb " ('\u2030' ^2) )) +
scale_x_discrete(labels = lbls) +
facet_wrap(paste(".~", sp_col, sep = ""), ncol = 3, scales = "free_y")
cairo_pdf(paste(wd, "SEAb.pdf", sep = "/"), family = "Times", height = 4, width = 8)
print(seab)
dev.off()
print("All models have been run. Check your working directory for the results")
return(list(summaries = summaries,
sea_b = sea_b,
sea_bt = sea_bt,
hdis = hdis,
diffs = diffs,
diff_glob = diff_glob,
p_sup = p_sup,
ellips = ellipses))
}
3.4.2 Sex
<- c("Female", "Male")
lbls <- custom_siber(full_set, var_col = "Sex", lbls, sp_col = "Species", n.burnin = 7000,
sex_siber colors = global_colors, gp_label = "Sex")
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 37
Unobserved stochastic nodes: 3
Total graph size: 52
Initializing model
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 44
Unobserved stochastic nodes: 3
Total graph size: 59
Initializing model
No id variables; using all as measure variables
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 55
Unobserved stochastic nodes: 3
Total graph size: 70
Initializing model
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 14
Unobserved stochastic nodes: 3
Total graph size: 29
Initializing model
No id variables; using all as measure variables
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 31
Unobserved stochastic nodes: 3
Total graph size: 46
Initializing model
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 43
Unobserved stochastic nodes: 3
Total graph size: 58
Initializing model
No id variables; using all as measure variables
Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
ℹ Please use tidy evaluation ideoms with `aes()`
[1] "All models have been run. Check your working directory for the results"
Plots of ellipses:
$ellips sex_siber
Eccentricities:
<- data.frame()
ecc for (sp in seq_along(species)) {
for (j in seq_along(lbls)) {
<- rbind(ecc,
ecc data.frame(sp = species[sp],
j = lbls[j],
ecc = apply(sex_siber$ellips[[species[sp]]][[j]][,1:4], 1, mat_ecc),
theta = apply(sex_siber$ellips[[species[sp]]][[j]][,1:4], 1, mat_theta)))
} }
<- ecc %>% group_by(sp, j) %>% summarise(IQR.lower = hdi(ecc, credMass = 0.5)[1],
ec IQR.upper = hdi(ecc, credMass = 0.5)[2],
hdi.lower = hdi(ecc)[1],
hdi.upper = hdi(ecc)[2],
mean = mean(ecc))
`summarise()` has grouped output by 'sp'. You can override using the `.groups`
argument.
ec
ggplot(data = ecc, aes(x = j, y = ecc, group = j, color = factor(j))) +
geom_violin(fill = NA, show.legend = F) +
#geom_point(aes(x = sp, y = mean), data = ag, show.legend = F) +
#geom_errorbar(aes(x = sp, ymin = IQ.lower, ymax = IQ.upper, group = sp), data = ag) +
geom_boxplot(width = 0.1, show.legend = F) +
theme_bw() +
labs(title = "SEAB Eccentricity",
x = element_blank(),
y = element_blank()) +
scale_color_manual(values = global_colors) +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.15, 0.1),
legend.background = element_blank()) +
facet_wrap(~sp)
Theta:
<- ecc %>% group_by(sp, j) %>% summarise(IQR.lower = hdi(theta, credMass = 0.5)[1],
th IQR.upper = hdi(theta, credMass = 0.5)[2],
hdi.lower = hdi(theta)[1],
hdi.upper = hdi(theta)[2],
mean = mean(theta))
`summarise()` has grouped output by 'sp'. You can override using the `.groups`
argument.
th
ggplot(data = ecc, aes(x = j, y = theta, group = j, color = factor(j))) +
geom_violin(fill = NA, show.legend = F) +
#geom_point(aes(x = sp, y = mean), data = ag, show.legend = F) +
#geom_errorbar(aes(x = sp, ymin = IQ.lower, ymax = IQ.upper, group = sp), data = ag) +
geom_boxplot(width = 0.1, show.legend = F) +
theme_bw() +
labs(title = "SEAB theta",
x = element_blank(),
y = element_blank()) +
scale_color_manual(values = global_colors) +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.15, 0.1),
legend.background = element_blank()) +
facet_wrap(~sp)
3.4.3 Maturity stages
<- c("Adult", "Juvenile")
lbls <- custom_siber(full_set, var_col = "Maturity", lbls, sp_col = "Species", n.burnin = 7000,
age_siber colors = global_colors, gp_label = "Age")
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 45
Unobserved stochastic nodes: 3
Total graph size: 60
Initializing model
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 36
Unobserved stochastic nodes: 3
Total graph size: 51
Initializing model
No id variables; using all as measure variables
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 55
Unobserved stochastic nodes: 3
Total graph size: 70
Initializing model
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 14
Unobserved stochastic nodes: 3
Total graph size: 29
Initializing model
No id variables; using all as measure variables
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 48
Unobserved stochastic nodes: 3
Total graph size: 63
Initializing model
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 26
Unobserved stochastic nodes: 3
Total graph size: 41
Initializing model
No id variables; using all as measure variables
[1] "All models have been run. Check your working directory for the results"
Plots of ellipses:
$ellips age_siber
Eccenctricities:
<- data.frame()
ecc for (sp in seq_along(species)) {
for (j in seq_along(lbls)) {
<- rbind(ecc,
ecc data.frame(sp = species[sp],
j = lbls[j],
ecc = apply(age_siber$ellips[[species[sp]]][[j]][,1:4], 1, mat_ecc),
theta = apply(age_siber$ellips[[species[sp]]][[j]][,1:4], 1, mat_theta)))
} }
<- ecc %>% group_by(sp, j) %>% summarise(IQR.lower = hdi(ecc, credMass = 0.5)[1],
ec IQR.upper = hdi(ecc, credMass = 0.5)[2],
hdi.lower = hdi(ecc)[1],
hdi.upper = hdi(ecc)[2],
mean = mean(ecc))
`summarise()` has grouped output by 'sp'. You can override using the `.groups`
argument.
ec
ggplot(data = ecc, aes(x = j, y = ecc, group = j, color = factor(j))) +
geom_violin(fill = NA, show.legend = F) +
#geom_point(aes(x = sp, y = mean), data = ag, show.legend = F) +
#geom_errorbar(aes(x = sp, ymin = IQ.lower, ymax = IQ.upper, group = sp), data = ag) +
geom_boxplot(width = 0.1, show.legend = F) +
theme_bw() +
labs(title = "SEAB Eccentricity",
x = element_blank(),
y = element_blank()) +
scale_color_manual(values = global_colors) +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.15, 0.1),
legend.background = element_blank()) +
facet_wrap(~sp)
Theta:
<- ecc %>% group_by(sp, j) %>% summarise(IQR.lower = hdi(theta, credMass = 0.5)[1],
th IQR.upper = hdi(theta, credMass = 0.5)[2],
hdi.lower = hdi(theta)[1],
hdi.upper = hdi(theta)[2],
mean = mean(theta))
`summarise()` has grouped output by 'sp'. You can override using the `.groups`
argument.
th
ggplot(data = ecc, aes(x = j, y = theta, group = j, color = factor(j))) +
geom_violin(fill = NA, show.legend = F) +
#geom_point(aes(x = sp, y = mean), data = ag, show.legend = F) +
#geom_errorbar(aes(x = sp, ymin = IQ.lower, ymax = IQ.upper, group = sp), data = ag) +
geom_boxplot(width = 0.1, show.legend = F) +
theme_bw() +
labs(title = "SEAB theta",
x = element_blank(),
y = element_blank()) +
scale_color_manual(values = global_colors) +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.15, 0.1),
legend.background = element_blank()) +
facet_wrap(~sp)
3.4.4 Season
<- c("Warm", "Cold")
lbls <- custom_siber(full_set, var_col = "Season", lbls, sp_col = "Species",
season_siber colors = global_colors, gp_label = "Season",
n.burnin = 750000, n.iter = 10000)
Too few points to calculate an ellipse
Warning: Removed 1 row containing missing values (`geom_path()`).
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 63
Unobserved stochastic nodes: 3
Total graph size: 78
Initializing model
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 18
Unobserved stochastic nodes: 3
Total graph size: 33
Initializing model
No id variables; using all as measure variables
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 15
Unobserved stochastic nodes: 3
Total graph size: 30
Initializing model
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 54
Unobserved stochastic nodes: 3
Total graph size: 69
Initializing model
No id variables; using all as measure variables
Warning in createSiberObject(subdata[subdata[, sp_col] == species[i], 3:6]): At least one of your groups has less than 5 observations.
The absolute minimum sample size for each group is 3 in order
for the various ellipses and corresponding metrics to be
calculated. More reasonably though, a minimum of 5 data points
are required to calculate the two means and the 2x2 covariance
matrix and not run out of degrees of freedom. Check the item
named 'sample.sizes' in the object returned by this function
in order to locate the offending group. Bear in mind that NAs in
the sample.size matrix simply indicate groups that are not
present in that community, and is an acceptable data structure
for these analyses.
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 71
Unobserved stochastic nodes: 3
Total graph size: 86
Initializing model
Compiling model graph
Resolving undeclared variables
Allocating nodes
Graph information:
Observed stochastic nodes: 3
Unobserved stochastic nodes: 3
Total graph size: 18
Initializing model
No id variables; using all as measure variables
[1] "All models have been run. Check your working directory for the results"
Plots of ellipses:
$ellips season_siber
<- data.frame()
ecc for (sp in seq_along(species)) {
for (j in seq_along(lbls)) {
<- rbind(ecc,
ecc data.frame(sp = species[sp],
j = lbls[j],
ecc = apply(season_siber$ellips[[species[sp]]][[j]][,1:4], 1, mat_ecc),
theta = apply(season_siber$ellips[[species[sp]]][[j]][,1:4], 1, mat_theta)))
} }
<- ecc %>% group_by(sp, j) %>% summarise(IQR.lower = hdi(ecc, credMass = 0.5)[1],
ec IQR.upper = hdi(ecc, credMass = 0.5)[2],
hdi.lower = hdi(ecc)[1],
hdi.upper = hdi(ecc)[2],
mean = mean(ecc))
`summarise()` has grouped output by 'sp'. You can override using the `.groups`
argument.
ec
ggplot(data = ecc, aes(x = j, y = ecc, group = j, color = factor(j))) +
geom_violin(fill = NA, show.legend = F) +
#geom_point(aes(x = sp, y = mean), data = ag, show.legend = F) +
#geom_errorbar(aes(x = sp, ymin = IQ.lower, ymax = IQ.upper, group = sp), data = ag) +
geom_boxplot(width = 0.1, show.legend = F) +
theme_bw() +
labs(title = "SEAB Eccentricity",
x = element_blank(),
y = element_blank()) +
scale_color_manual(values = global_colors) +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.15, 0.1),
legend.background = element_blank()) +
facet_wrap(~sp)
Theta:
<- ecc %>% group_by(sp, j) %>% summarise(IQR.lower = hdi(theta, credMass = 0.5)[1],
th IQR.upper = hdi(theta, credMass = 0.5)[2],
hdi.lower = hdi(theta)[1],
hdi.upper = hdi(theta)[2],
mean = mean(theta))
`summarise()` has grouped output by 'sp'. You can override using the `.groups`
argument.
th
ggplot(data = ecc, aes(x = j, y = theta, group = j, color = factor(j))) +
geom_violin(fill = NA, show.legend = F) +
#geom_point(aes(x = sp, y = mean), data = ag, show.legend = F) +
#geom_errorbar(aes(x = sp, ymin = IQ.lower, ymax = IQ.upper, group = sp), data = ag) +
geom_boxplot(width = 0.1, show.legend = F) +
theme_bw() +
labs(title = "SEAB theta",
x = element_blank(),
y = element_blank()) +
scale_color_manual(values = global_colors) +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.15, 0.1),
legend.background = element_blank()) +
facet_wrap(~sp)
3.4.5 Final forestplot:
<- rbind(age_siber[[6]], season_siber[[6]], sex_siber[[6]])
forest_data
<- ggplot(data = forest_data) +
forest geom_vline(xintercept = 0, linetype = "dashed", color = "#C9C8C8", size = 0.5) +
geom_linerange(aes(y = comp, xmin = IQr.lower, xmax = IQr.upper),
color = global_colors[1], size = 1) +
geom_linerange(aes(y = comp, xmin = hdi.lower, xmax = hdi.upper),
color = global_colors[1]) +
geom_point(aes(x = mean, y = comp),
color = global_colors[1], fill = "white", size = 1.5, shape = 21) +
theme_bw() +
theme(aspect.ratio = 1,
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = c(0.2, 0.15),
legend.background = element_blank()) +
scale_x_continuous(breaks = scales::pretty_breaks(n = 3)) +
labs(title = element_blank(),
x = element_blank(),
y = element_blank()) + facet_wrap(~sp)
# cairo_pdf("output/SIBER/forest_cats.pdf", family = "Times", width = 4, height = 2)
forest
# dev.off()
Tabular results:
Seasons:
$diff_glob[,c("comp", "sp", "mean")] season_siber
$p_sup season_siber
Sexes:
$diff_glob[,c("comp", "sp", "mean")] sex_siber
$p_sup sex_siber
Maturity stages:
$diff_glob[,c("comp", "sp", "mean")] age_siber
$p_sup age_siber