Main figures
# https://mjskay.github.io/tidybayes/articles/tidy-brms.html
# m1 <- readRDS("output/vbge/m1.rds")
pal <- rev(brewer.pal(n = 6, name = "Paired")[c(2, 6)])
# Plot main predictions
pvbge <- d %>%
data_grid(age = seq_range(age, by = 1),
area = c("FM", "BT")) %>%
mutate(areaC = ifelse(area == "FM", 1, 0),
areaW = ifelse(area == "BT", 1, 0)) %>%
add_predicted_draws(m1, re_formula = NA) %>%
ggplot(aes(x = factor(age), y = length_cm, color = area, fill = area)) +
stat_lineribbon(aes(y = exp(.prediction)), .width = c(.5, 0.9), alpha = 0.2, size = 0.8) +
geom_jitter(data = d, alpha = 0.1, width = 0.3, height = 0, size = 0.8) +
stat_lineribbon(aes(y = exp(.prediction)), .width = 0, alpha = 0.8, size = 0.8) +
guides(fill = "none",
color = guide_legend(override.aes = list(linetype = 0, fill = NA,
size = 3, shape = 16, alpha = 0.5))) +
scale_fill_manual(values = pal, labels = c("Heated", "Reference")) +
scale_color_manual(values = pal, labels = c("Heated", "Reference")) +
labs(y = "Length [cm]", x = "Age [yrs]", fill = "Area", colour = "Area") +
annotate("text", 8, 10, label = paste("n=", nrow(d), sep = ""), size = 3) +
theme(text = element_text(size = 12), # 12 for word doc
legend.position = c(0.1, 0.9),
legend.spacing.y = unit(0, 'cm'),
legend.key.size = unit(0, "cm"),
legend.title = element_text(size = 10),
legend.text = element_text(size = 10))
#> mutate: new variable 'areaC' (double) with 2 unique values and 0% NA
#> new variable 'areaW' (double) with 2 unique values and 0% NA
# Plotting mcmc_dens and use patchwork to plot them together. Note I add the vertical
# lines manually simply by extracting the fixed effects
m1_fe <- fixef(m1, probs = c(0.1, 0.9)) %>% as.data.frame()
posterior <- as.array(m1)
# http://mjskay.github.io/tidybayes/articles/tidy-brms.html
post_K <-
m1 %>%
gather_draws(b_KC_Intercept, b_KW_Intercept) %>%
ggplot(aes(x = .value, fill = .variable, color = .variable)) +
stat_halfeye(alpha = 0.5, size = 5, .width = c(0.7)) +
guides(fill = guide_legend(override.aes = list(size = 1, shape = NA, linetype = 0)),
color = "none") +
#guides(fill = "none", color = "none") +
scale_fill_manual(values = rev(pal), labels = c("Ref", "Heat")) +
scale_color_manual(values = rev(pal)) +
labs(x = expression(paste(italic(K), " [", yr^-1,"]", sep = "")), fill = "") +
theme(legend.position = c(0.9, 0.9),
legend.key.size = unit(0.2, "cm"),
legend.background = element_blank())
post_L_inf <-
m1 %>%
gather_draws(b_LinfC_Intercept, b_LinfW_Intercept) %>%
ggplot(aes(x = .value, fill = .variable, color = .variable)) +
stat_halfeye(alpha = 0.5, size = 5, .width = c(0.7)) +
# guides(fill = guide_legend(override.aes = list(size = 1, shape = NA, linetype = 0)),
# color = "none") +
guides(fill = "none", color = "none") +
scale_fill_manual(values = rev(pal), labels = c("Cold", "Warm")) +
scale_color_manual(values = rev(pal)) +
labs(x = expression(paste(italic(L[infinity]), " [cm]")), fill = "") +
theme(legend.position = c(0.9, 0.9),
legend.key.size = unit(0.2, "cm"),
legend.background = element_blank())
# Plot distribution of differences
# http://mjskay.github.io/tidybayes/articles/tidy-brms.html
diff <- m1 %>%
spread_draws(b_LinfC_Intercept, b_LinfW_Intercept, b_KC_Intercept, b_KW_Intercept) %>%
mutate(diff_K = b_KW_Intercept - b_KC_Intercept,
diff_L_inf = b_LinfW_Intercept - b_LinfC_Intercept)
#> mutate: new variable 'diff_K' (double) with 6,000 unique values and 0% NA
#> new variable 'diff_L_inf' (double) with 6,000 unique values and 0% NA
prop_diff_K <- summarise(diff, Proportion_of_the_difference_below_0 = sum(diff_K < 0) / length(diff_K))
#> summarise: now one row and one column, ungrouped
prop_diff_L_inf <- summarise(diff, Proportion_of_the_difference_below_0 = sum(diff_L_inf < 0) / length(diff_L_inf))
#> summarise: now one row and one column, ungrouped
round(prop_diff_K, 2)
round(prop_diff_L_inf, 2)
# https://bookdown.org/content/3890/interactions.html
post_diff_K <- ggplot(diff, aes(x = diff_K, fill = stat(x > 0))) +
stat_halfeye(alpha = 0.5, size = 5, .width = 0) +
guides(fill = guide_legend(override.aes = list(size = 1, shape = NA, linetype = 0)), color = "none") +
scale_fill_manual(values = c("grey10", "grey70")) +
#annotate("text", 0.01, 0.95, size = 3, label = paste("Proportion of difference < 0=", round(prop_diff_K, 2), sep = "")) +
labs(x = expression(~italic(K)[heat]~-~italic(K)[ref])) +
theme(legend.position = c(0.2, 0.7),
legend.key.size = unit(0.2, "cm"),
legend.text = element_text(size = 8),
legend.title = element_text(size = 10),
legend.background = element_blank())
post_diff_L_inf <- ggplot(diff, aes(x = diff_L_inf, fill = stat(x > 0))) +
stat_halfeye(alpha = 0.5, size = 5, .width = 0) +
guides(fill = guide_legend(override.aes = list(size = 1, shape = NA, linetype = 0)), color = "none") +
scale_fill_manual(values = c("grey10", "grey70")) +
#annotate("text", 0, 0.95, size = 3, label = paste("Proportion of difference < 0 =", round(prop_diff_L_inf, 2), sep = "")) +
labs(x = expression(paste(~italic(L[infinity])[heat]~-~italic(L[infinity])[ref]))) +
theme(legend.position = c(0.2, 0.7),
legend.key.size = unit(0.2, "cm"),
legend.text = element_text(size = 8),
legend.title = element_text(size = 10),
legend.background = element_blank())
pvbge

ggsave("figures/vbge_pred.pdf", width = 20, height = 20, unit = "cm")
#ggsave("figures/vbge_pred_K_Linf_post.png", width = 6.5, height = 6.5, dpi = 600)
((post_K/post_diff_K) | (post_L_inf/post_diff_L_inf)) +
plot_layout(heights = c(1.2, 1)) +
plot_annotation(tag_levels = 'A')

ggsave("figures/supp/vbge_K_Linf_post.pdf", width = 20, height = 20, unit = "cm")
Supporting figures
Random year effects
# http://mjskay.github.io/tidybayes/articles/tidy-brms.html
pal2 <- alpha(pal, alpha = 0.8)
# Plot predictions by cohort:
p2 <- d %>%
data_grid(age = seq_range(age, by = 1),
birth_year = seq_range(birth_year, by = 1),
area = c("FM", "BT")) %>%
mutate(areaC = ifelse(area == "FM", 1, 0),
areaW = ifelse(area == "BT", 1, 0)) %>%
add_predicted_draws(m1) %>%
ggplot(aes(x = factor(age), y = length_cm, color = area, fill = area)) +
stat_lineribbon(aes(y = exp(.prediction)), .width = .95, alpha = 0.4, size = 0.5) +
stat_lineribbon(aes(y = exp(.prediction)), .width = 0, alpha = 0.8, size = 0.5) +
geom_jitter(data = d, alpha = 0.2, width = 0.3,
height = 0, size = 0.6) +
facet_wrap(~birth_year) +
scale_fill_manual(values = pal2, labels = c("Warm", "Cold")) +
scale_color_manual(values = pal2, labels = c("Warm", "Cold")) +
labs(y = "Length [cm]", x = "Age [yrs]", fill = "Area", colour = "Area") +
NULL
#> mutate: new variable 'areaC' (double) with 2 unique values and 0% NA
#> new variable 'areaW' (double) with 2 unique values and 0% NA
pWord2 <- p2 + theme(text = element_text(size = 12),
legend.position = c(0.7, 0.1),
legend.title = element_text(size = 12),
legend.text = element_text(size = 12))
#ggsave("figures/supp/vbge_pred_cohort.png", width = 6.5, height = 6.5, dpi = 600)
ggsave("figures/supp/vbge_pred_cohort.pdf", width = 20, height = 20, unit = "cm")
# Cohort-specific VBGE parameters
get_variables(m1)
#> [1] "b_t0C_Intercept" "b_t0W_Intercept"
#> [3] "b_KC_Intercept" "b_KW_Intercept"
#> [5] "b_LinfC_Intercept" "b_LinfW_Intercept"
#> [7] "sd_birth_year__KC_Intercept" "sd_birth_year__KW_Intercept"
#> [9] "sd_birth_year__LinfC_Intercept" "sd_birth_year__LinfW_Intercept"
#> [11] "sigma" "nu"
#> [13] "r_birth_year__KC[1981,Intercept]" "r_birth_year__KC[1982,Intercept]"
#> [15] "r_birth_year__KC[1983,Intercept]" "r_birth_year__KC[1984,Intercept]"
#> [17] "r_birth_year__KC[1985,Intercept]" "r_birth_year__KC[1986,Intercept]"
#> [19] "r_birth_year__KC[1987,Intercept]" "r_birth_year__KC[1988,Intercept]"
#> [21] "r_birth_year__KC[1989,Intercept]" "r_birth_year__KC[1990,Intercept]"
#> [23] "r_birth_year__KC[1991,Intercept]" "r_birth_year__KC[1992,Intercept]"
#> [25] "r_birth_year__KC[1993,Intercept]" "r_birth_year__KC[1994,Intercept]"
#> [27] "r_birth_year__KC[1995,Intercept]" "r_birth_year__KC[1996,Intercept]"
#> [29] "r_birth_year__KC[1997,Intercept]" "r_birth_year__KW[1981,Intercept]"
#> [31] "r_birth_year__KW[1982,Intercept]" "r_birth_year__KW[1983,Intercept]"
#> [33] "r_birth_year__KW[1984,Intercept]" "r_birth_year__KW[1985,Intercept]"
#> [35] "r_birth_year__KW[1986,Intercept]" "r_birth_year__KW[1987,Intercept]"
#> [37] "r_birth_year__KW[1988,Intercept]" "r_birth_year__KW[1989,Intercept]"
#> [39] "r_birth_year__KW[1990,Intercept]" "r_birth_year__KW[1991,Intercept]"
#> [41] "r_birth_year__KW[1992,Intercept]" "r_birth_year__KW[1993,Intercept]"
#> [43] "r_birth_year__KW[1994,Intercept]" "r_birth_year__KW[1995,Intercept]"
#> [45] "r_birth_year__KW[1996,Intercept]" "r_birth_year__KW[1997,Intercept]"
#> [47] "r_birth_year__LinfC[1981,Intercept]" "r_birth_year__LinfC[1982,Intercept]"
#> [49] "r_birth_year__LinfC[1983,Intercept]" "r_birth_year__LinfC[1984,Intercept]"
#> [51] "r_birth_year__LinfC[1985,Intercept]" "r_birth_year__LinfC[1986,Intercept]"
#> [53] "r_birth_year__LinfC[1987,Intercept]" "r_birth_year__LinfC[1988,Intercept]"
#> [55] "r_birth_year__LinfC[1989,Intercept]" "r_birth_year__LinfC[1990,Intercept]"
#> [57] "r_birth_year__LinfC[1991,Intercept]" "r_birth_year__LinfC[1992,Intercept]"
#> [59] "r_birth_year__LinfC[1993,Intercept]" "r_birth_year__LinfC[1994,Intercept]"
#> [61] "r_birth_year__LinfC[1995,Intercept]" "r_birth_year__LinfC[1996,Intercept]"
#> [63] "r_birth_year__LinfC[1997,Intercept]" "r_birth_year__LinfW[1981,Intercept]"
#> [65] "r_birth_year__LinfW[1982,Intercept]" "r_birth_year__LinfW[1983,Intercept]"
#> [67] "r_birth_year__LinfW[1984,Intercept]" "r_birth_year__LinfW[1985,Intercept]"
#> [69] "r_birth_year__LinfW[1986,Intercept]" "r_birth_year__LinfW[1987,Intercept]"
#> [71] "r_birth_year__LinfW[1988,Intercept]" "r_birth_year__LinfW[1989,Intercept]"
#> [73] "r_birth_year__LinfW[1990,Intercept]" "r_birth_year__LinfW[1991,Intercept]"
#> [75] "r_birth_year__LinfW[1992,Intercept]" "r_birth_year__LinfW[1993,Intercept]"
#> [77] "r_birth_year__LinfW[1994,Intercept]" "r_birth_year__LinfW[1995,Intercept]"
#> [79] "r_birth_year__LinfW[1996,Intercept]" "r_birth_year__LinfW[1997,Intercept]"
#> [81] "lprior" "lp__"
#> [83] "accept_stat__" "stepsize__"
#> [85] "treedepth__" "n_leapfrog__"
#> [87] "divergent__" "energy__"
# Warm K
pKW <- m1 %>%
spread_draws(b_KW_Intercept,
r_birth_year__KW[birth_year, Intercept]) %>%
mutate(year_mean_KW = b_KW_Intercept + r_birth_year__KW) %>% # The random effects are offsets
ggplot(aes(y = factor(birth_year), x = year_mean_KW)) +
stat_halfeye(fill = pal2[1], alpha = 0.8, point_interval = median_qi, .width = 0.95) +
labs(y = "Cohort", x = expression(paste(italic(K), " [", yr^-1,"]", sep = ""))) +
ggtitle("Warm")
#> Warning: `gather_()` was deprecated in tidyr 1.2.0.
#> ℹ Please use `gather()` instead.
#> ℹ The deprecated feature was likely used in the tidybayes package.
#> Please report the issue at <]8;;https://github.com/mjskay/tidybayes/issues/newhttps://github.com/mjskay/tidybayes/issues/new]8;;>.
#> mutate (grouped): new variable 'year_mean_KW' (double) with 102,000 unique values and 0% NA
# Cold K
pKC <- m1 %>%
spread_draws(b_KC_Intercept,
r_birth_year__KC[birth_year, Intercept]) %>%
mutate(year_mean_KC = b_KC_Intercept + r_birth_year__KC) %>% # The random effects are offsets
ggplot(aes(y = factor(birth_year), x = year_mean_KC)) +
stat_halfeye(fill = pal2[2], alpha = 0.8, point_interval = median_qi, .width = 0.95) +
labs(y = "Cohort", x = expression(paste(italic(K), " [", yr^-1,"]", sep = ""))) +
ggtitle("Cold")
#> mutate (grouped): new variable 'year_mean_KC' (double) with 102,000 unique values and 0% NA
pKW + pKC

#ggsave("figures/supp/vbge_random_K.png", width = 6.5, height = 6.5, dpi = 600)
ggsave("figures/supp/vbge_random_K.pdf", width = 20, height = 20, unit = "cm")
# Warm L_inf
pLinfW <- m1 %>%
spread_draws(b_LinfW_Intercept,
r_birth_year__LinfW[birth_year, Intercept]) %>%
mutate(year_mean_LinfW = b_LinfW_Intercept + r_birth_year__LinfW) %>% # The random effects are offsets
ggplot(aes(y = factor(birth_year), x = year_mean_LinfW)) +
stat_halfeye(fill = pal2[1], alpha = 0.8, point_interval = median_qi, .width = 0.95) +
labs(y = "Cohort", x = expression(paste(italic(L[infinity]), " [cm]"))) +
coord_cartesian(xlim = c(26, 100)) +
ggtitle("Warm")
#> mutate (grouped): new variable 'year_mean_LinfW' (double) with 102,000 unique values and 0% NA
# Cold L_inf
pLinfC <- m1 %>%
spread_draws(b_LinfC_Intercept,
r_birth_year__LinfC[birth_year, Intercept]) %>%
mutate(year_mean_LinfC = b_LinfC_Intercept + r_birth_year__LinfC) %>% # The random effects are offsets
ggplot(aes(y = factor(birth_year), x = year_mean_LinfC)) +
stat_halfeye(fill = pal2[2], alpha = 0.8, point_interval = median_qi, .width = 0.95) +
labs(y = "Cohort", x = expression(paste(italic(L[infinity]), " [cm]"))) +
coord_cartesian(xlim = c(26, 100)) +
ggtitle("Cold")
#> mutate (grouped): new variable 'year_mean_LinfC' (double) with 102,000 unique values and 0% NA
pLinfW + pLinfC

#ggsave("figures/supp/vbge_random_Linf.png", width = 6.5, height = 6.5, dpi = 600)
ggsave("figures/supp/vbge_random_Linf.pdf", width = 20, height = 20, unit = "cm")
Prior vs posterior
# https://discourse.mc-stan.org/t/presenting-influence-of-different-priors/23393
# Refit model and sample prior or load below (m1_w_prior)
prior <-
prior(normal(-0.5, 1), nlpar = "t0C") +
prior(normal(-0.5, 1), nlpar = "t0W") +
prior(normal(0.2, 0.1), nlpar = "KC") +
prior(normal(0.2, 0.1), nlpar = "KW") +
prior(normal(45, 20), nlpar = "LinfC") +
prior(normal(45, 20), nlpar = "LinfW")
m1_w_prior <-
brm(
bf(log(length_cm) ~ areaW*log(LinfW*(1-exp(-KW*(age-t0W)))) + areaC*log(LinfC*(1-exp(-KC*(age-t0C)))),
t0C ~ 1,
t0W ~ 1,
KC ~ 1 + (1|birth_year), # parameter varying by birth_year
KW ~ 1 + (1|birth_year), # parameter varying by birth_year
LinfC ~ 1 + (1|birth_year), # parameter varying by birth_year
LinfW ~ 1 + (1|birth_year), # parameter varying by birth_year
nl = TRUE),
data = d,
family = student(), prior = prior, sample_prior = "yes", seed = 9,
iter = 4000, thin = 1, cores = 3, chains = 3, inits = inits_3_chain,
control = list(max_treedepth = 13, adapt_delta = 0.99))
#> Warning: Argument 'inits' is deprecated. Please use argument 'init' instead.
#> Compiling Stan program...
#> Start sampling
# saveRDS(m1_w_prior, "output/vbge/m1_w_prior.rds")
# m1_w_prior <- readRDS("output/vbge/m1_w_prior.rds")
post <- m1_w_prior %>%
posterior_samples() %>%
clean_names() %>%
dplyr::select(b_linf_w_intercept, b_linf_c_intercept, b_kw_intercept, b_kc_intercept, b_t0w_intercept, b_t0c_intercept,
prior_b_linf_w, prior_b_linf_c, prior_b_kw, prior_b_kc, prior_b_t0w, prior_b_t0c)
#> Warning: Method 'posterior_samples' is deprecated. Please see ?as_draws for
#> recommended alternatives.
post_long <- post %>% pivot_longer(cols = c(1:12), names_to = "Parameter", values_to = "value")
#> pivot_longer: reorganized (b_linf_w_intercept, b_linf_c_intercept, b_kw_intercept, b_kc_intercept, b_t0w_intercept, …) into (Parameter, value) [was 6000x12, now 72000x2]
# parameter Linf
prior_post_linf <- post_long %>%
filter(Parameter %in% c("b_linf_w_intercept", "b_linf_c_intercept", "prior_b_linf_w", "prior_b_linf_c")) %>%
ggplot(., aes(value, fill = Parameter, color = Parameter, alpha = Parameter))+
geom_density() +
labs(x = expression(italic(L[infinity]))) +
coord_cartesian(expand = 0) +
scale_alpha_manual(values = c(0.4, 0.4, 0.1, 0.1)) +
scale_color_manual(values = c(NA, NA, "gray50", "gray50")) +
scale_fill_manual(values = c(pal[2], pal[1], NA, NA),
labels = c(expression(paste(~italic(L[infinity])[ref])),
expression(paste(~italic(L[infinity])[heat])),
expression(paste(Prior~italic(L[infinity])[heat])),
expression(paste(Prior~italic(L[infinity])[ref])))) +
guides(color = "none", alpha = "none",
fill = guide_legend(override.aes = list(color = c(NA, NA, "gray50", "gray50"),
alpha = c(0.4, 0.4, 0.1, 0.1)))) +
theme(legend.position = c(0.2, 0.8),
legend.text.align = 0)
#> filter: removed 48,000 rows (67%), 24,000 rows remaining
# parameter K
prior_post_K <- post_long %>%
filter(Parameter %in% c("b_kw_intercept", "b_kc_intercept", "prior_b_kw", "prior_b_kc")) %>%
ggplot(., aes(value, fill = Parameter, color = Parameter, alpha = Parameter))+
geom_density() +
labs(x = expression(italic(K))) +
coord_cartesian(expand = 0) +
scale_alpha_manual(values = c(0.4, 0.4, 0.1, 0.1)) +
scale_color_manual(values = c(NA, NA, "gray50", "gray50")) +
scale_fill_manual(values = c(pal[2], pal[1], NA, NA),
labels = c(expression(italic(K)[ref]),
expression(italic(K)[heat]),
expression(paste(Prior~italic(K)[heat])),
expression(paste(Prior~italic(K)[ref])))) +
guides(color = "none", alpha = "none",
fill = guide_legend(override.aes = list(color = c(NA, NA, "gray50", "gray50"),
alpha = c(0.4, 0.4, 0.1, 0.1)))) +
theme(legend.position = c(0.2, 0.8),
legend.text.align = 0)
#> filter: removed 48,000 rows (67%), 24,000 rows remaining
# parameter t0
prior_post_t0 <- post_long %>%
filter(Parameter %in% c("b_t0w_intercept", "b_t0c_intercept", "prior_b_t0w", "prior_b_t0c")) %>%
ggplot(., aes(value, fill = Parameter, color = Parameter, alpha = Parameter))+
geom_density() +
labs(x = expression(italic(t[0]))) +
coord_cartesian(expand = 0) +
scale_alpha_manual(values = c(0.4, 0.4, 0.1, 0.1)) +
scale_color_manual(values = c(NA, NA, "gray50", "gray50")) +
scale_fill_manual(values = c(pal[2], pal[1], NA, NA),
labels = c(expression(italic(t[0])[ref]),
expression(italic(t[0])[heat]),
expression(paste(Prior~italic(t[0])[ref])),
expression(paste(Prior~italic(t[0])[heat])))) +
guides(color = "none", alpha = "none",
fill = guide_legend(override.aes = list(color = c(NA, NA, "gray50", "gray50"),
alpha = c(0.4, 0.4, 0.1, 0.1)))) +
theme(legend.position = c(0.2, 0.8),
legend.text.align = 0)
#> filter: removed 48,000 rows (67%), 24,000 rows remaining
prior_post_linf / prior_post_K / prior_post_t0 +
plot_annotation(tag_levels = "A")

ggsave("figures/supp/vbge_prior_post.pdf", width = 20, height = 20, unit = "cm")
Size difference by age class
# Plot % difference by age class
fm_preds <- d %>%
data_grid(age = seq_range(age, by = 1),
area = c("FM")) %>%
mutate(areaC = ifelse(area == "FM", 1, 0),
areaW = ifelse(area == "BT", 1, 0)) %>%
add_epred_draws(m1, re_formula = NA, seed = 5) %>%
ungroup() %>%
rename(FM_pred = .epred) %>%
dplyr::select(-area, -areaC, -areaW)
#> mutate: new variable 'areaC' (double) with one unique value and 0% NA
#> new variable 'areaW' (double) with one unique value and 0% NA
#> ungroup: no grouping variables
#> rename: renamed one variable (FM_pred)
bt_preds <- d %>%
data_grid(age = seq_range(age, by = 1),
area = c("BT")) %>%
mutate(areaC = ifelse(area == "FM", 1, 0),
areaW = ifelse(area == "BT", 1, 0)) %>%
add_epred_draws(m1, re_formula = NA, seed = 5) %>%
ungroup() %>%
rename(BT_pred = .epred) %>%
dplyr::select(-area, -areaC, -areaW)
#> mutate: new variable 'areaC' (double) with one unique value and 0% NA
#> new variable 'areaW' (double) with one unique value and 0% NA
#> ungroup: no grouping variables
#> rename: renamed one variable (BT_pred)
ratio_df <- left_join(fm_preds, bt_preds) %>%
mutate(heated_ref_ratio = (BT_pred/FM_pred))
#> Joining, by = c("age", ".row", ".chain", ".iteration", ".draw")
#> left_join: added one column (BT_pred)
#> > rows only in x 0
#> > rows only in y ( 0)
#> > matched rows 54,000
#> > ========
#> > rows total 54,000
#> mutate: new variable 'heated_ref_ratio' (double) with 54,000 unique values and 0% NA
size_ratio <- ggplot(ratio_df, aes(factor(age), heated_ref_ratio)) +
geom_violin(fill = "grey50", color = NA) +
geom_pointrange(stat = "summary",
fun.min = function(z) { quantile(z,0.25) },
fun.max = function(z) { quantile(z,0.75) },
fun = median, color = "white") +
geom_hline(yintercept = 1, linetype = 2, color = "gray50") +
coord_cartesian(ylim = c(0.85, 1.35)) +
labs(y = "Heated / Reference size-at-age", x = "Age [yrs]") +
theme(text = element_text(size = 12), # 12 for word doc
legend.position = c(0.1, 0.9),
legend.spacing.y = unit(0, 'cm'),
legend.key.size = unit(0, "cm"),
legend.title = element_text(size = 10),
legend.text = element_text(size = 10)) +
NULL
size_ratio

ggsave("figures/supp/vbge_size_age_ratios.pdf", width = 20, height = 20, unit = "cm")
Model diagnostics & fit
pal_diag <- rev(brewer.pal(n = 3, name = "Dark2"))
# Chain convergence
posterior <- as.array(m1)
dimnames(posterior)
#> $iteration
#> [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10"
#> [11] "11" "12" "13" "14" "15" "16" "17" "18" "19" "20"
#> [21] "21" "22" "23" "24" "25" "26" "27" "28" "29" "30"
#> [31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40"
#> [41] "41" "42" "43" "44" "45" "46" "47" "48" "49" "50"
#> [51] "51" "52" "53" "54" "55" "56" "57" "58" "59" "60"
#> [61] "61" "62" "63" "64" "65" "66" "67" "68" "69" "70"
#> [71] "71" "72" "73" "74" "75" "76" "77" "78" "79" "80"
#> [81] "81" "82" "83" "84" "85" "86" "87" "88" "89" "90"
#> [91] "91" "92" "93" "94" "95" "96" "97" "98" "99" "100"
#> [101] "101" "102" "103" "104" "105" "106" "107" "108" "109" "110"
#> [111] "111" "112" "113" "114" "115" "116" "117" "118" "119" "120"
#> [121] "121" "122" "123" "124" "125" "126" "127" "128" "129" "130"
#> [131] "131" "132" "133" "134" "135" "136" "137" "138" "139" "140"
#> [141] "141" "142" "143" "144" "145" "146" "147" "148" "149" "150"
#> [151] "151" "152" "153" "154" "155" "156" "157" "158" "159" "160"
#> [161] "161" "162" "163" "164" "165" "166" "167" "168" "169" "170"
#> [171] "171" "172" "173" "174" "175" "176" "177" "178" "179" "180"
#> [181] "181" "182" "183" "184" "185" "186" "187" "188" "189" "190"
#> [191] "191" "192" "193" "194" "195" "196" "197" "198" "199" "200"
#> [201] "201" "202" "203" "204" "205" "206" "207" "208" "209" "210"
#> [211] "211" "212" "213" "214" "215" "216" "217" "218" "219" "220"
#> [221] "221" "222" "223" "224" "225" "226" "227" "228" "229" "230"
#> [231] "231" "232" "233" "234" "235" "236" "237" "238" "239" "240"
#> [241] "241" "242" "243" "244" "245" "246" "247" "248" "249" "250"
#> [251] "251" "252" "253" "254" "255" "256" "257" "258" "259" "260"
#> [261] "261" "262" "263" "264" "265" "266" "267" "268" "269" "270"
#> [271] "271" "272" "273" "274" "275" "276" "277" "278" "279" "280"
#> [281] "281" "282" "283" "284" "285" "286" "287" "288" "289" "290"
#> [291] "291" "292" "293" "294" "295" "296" "297" "298" "299" "300"
#> [301] "301" "302" "303" "304" "305" "306" "307" "308" "309" "310"
#> [311] "311" "312" "313" "314" "315" "316" "317" "318" "319" "320"
#> [321] "321" "322" "323" "324" "325" "326" "327" "328" "329" "330"
#> [331] "331" "332" "333" "334" "335" "336" "337" "338" "339" "340"
#> [341] "341" "342" "343" "344" "345" "346" "347" "348" "349" "350"
#> [351] "351" "352" "353" "354" "355" "356" "357" "358" "359" "360"
#> [361] "361" "362" "363" "364" "365" "366" "367" "368" "369" "370"
#> [371] "371" "372" "373" "374" "375" "376" "377" "378" "379" "380"
#> [381] "381" "382" "383" "384" "385" "386" "387" "388" "389" "390"
#> [391] "391" "392" "393" "394" "395" "396" "397" "398" "399" "400"
#> [401] "401" "402" "403" "404" "405" "406" "407" "408" "409" "410"
#> [411] "411" "412" "413" "414" "415" "416" "417" "418" "419" "420"
#> [421] "421" "422" "423" "424" "425" "426" "427" "428" "429" "430"
#> [431] "431" "432" "433" "434" "435" "436" "437" "438" "439" "440"
#> [441] "441" "442" "443" "444" "445" "446" "447" "448" "449" "450"
#> [451] "451" "452" "453" "454" "455" "456" "457" "458" "459" "460"
#> [461] "461" "462" "463" "464" "465" "466" "467" "468" "469" "470"
#> [471] "471" "472" "473" "474" "475" "476" "477" "478" "479" "480"
#> [481] "481" "482" "483" "484" "485" "486" "487" "488" "489" "490"
#> [491] "491" "492" "493" "494" "495" "496" "497" "498" "499" "500"
#> [501] "501" "502" "503" "504" "505" "506" "507" "508" "509" "510"
#> [511] "511" "512" "513" "514" "515" "516" "517" "518" "519" "520"
#> [521] "521" "522" "523" "524" "525" "526" "527" "528" "529" "530"
#> [531] "531" "532" "533" "534" "535" "536" "537" "538" "539" "540"
#> [541] "541" "542" "543" "544" "545" "546" "547" "548" "549" "550"
#> [551] "551" "552" "553" "554" "555" "556" "557" "558" "559" "560"
#> [561] "561" "562" "563" "564" "565" "566" "567" "568" "569" "570"
#> [571] "571" "572" "573" "574" "575" "576" "577" "578" "579" "580"
#> [581] "581" "582" "583" "584" "585" "586" "587" "588" "589" "590"
#> [591] "591" "592" "593" "594" "595" "596" "597" "598" "599" "600"
#> [601] "601" "602" "603" "604" "605" "606" "607" "608" "609" "610"
#> [611] "611" "612" "613" "614" "615" "616" "617" "618" "619" "620"
#> [621] "621" "622" "623" "624" "625" "626" "627" "628" "629" "630"
#> [631] "631" "632" "633" "634" "635" "636" "637" "638" "639" "640"
#> [641] "641" "642" "643" "644" "645" "646" "647" "648" "649" "650"
#> [651] "651" "652" "653" "654" "655" "656" "657" "658" "659" "660"
#> [661] "661" "662" "663" "664" "665" "666" "667" "668" "669" "670"
#> [671] "671" "672" "673" "674" "675" "676" "677" "678" "679" "680"
#> [681] "681" "682" "683" "684" "685" "686" "687" "688" "689" "690"
#> [691] "691" "692" "693" "694" "695" "696" "697" "698" "699" "700"
#> [701] "701" "702" "703" "704" "705" "706" "707" "708" "709" "710"
#> [711] "711" "712" "713" "714" "715" "716" "717" "718" "719" "720"
#> [721] "721" "722" "723" "724" "725" "726" "727" "728" "729" "730"
#> [731] "731" "732" "733" "734" "735" "736" "737" "738" "739" "740"
#> [741] "741" "742" "743" "744" "745" "746" "747" "748" "749" "750"
#> [751] "751" "752" "753" "754" "755" "756" "757" "758" "759" "760"
#> [761] "761" "762" "763" "764" "765" "766" "767" "768" "769" "770"
#> [771] "771" "772" "773" "774" "775" "776" "777" "778" "779" "780"
#> [781] "781" "782" "783" "784" "785" "786" "787" "788" "789" "790"
#> [791] "791" "792" "793" "794" "795" "796" "797" "798" "799" "800"
#> [801] "801" "802" "803" "804" "805" "806" "807" "808" "809" "810"
#> [811] "811" "812" "813" "814" "815" "816" "817" "818" "819" "820"
#> [821] "821" "822" "823" "824" "825" "826" "827" "828" "829" "830"
#> [831] "831" "832" "833" "834" "835" "836" "837" "838" "839" "840"
#> [841] "841" "842" "843" "844" "845" "846" "847" "848" "849" "850"
#> [851] "851" "852" "853" "854" "855" "856" "857" "858" "859" "860"
#> [861] "861" "862" "863" "864" "865" "866" "867" "868" "869" "870"
#> [871] "871" "872" "873" "874" "875" "876" "877" "878" "879" "880"
#> [881] "881" "882" "883" "884" "885" "886" "887" "888" "889" "890"
#> [891] "891" "892" "893" "894" "895" "896" "897" "898" "899" "900"
#> [901] "901" "902" "903" "904" "905" "906" "907" "908" "909" "910"
#> [911] "911" "912" "913" "914" "915" "916" "917" "918" "919" "920"
#> [921] "921" "922" "923" "924" "925" "926" "927" "928" "929" "930"
#> [931] "931" "932" "933" "934" "935" "936" "937" "938" "939" "940"
#> [941] "941" "942" "943" "944" "945" "946" "947" "948" "949" "950"
#> [951] "951" "952" "953" "954" "955" "956" "957" "958" "959" "960"
#> [961] "961" "962" "963" "964" "965" "966" "967" "968" "969" "970"
#> [971] "971" "972" "973" "974" "975" "976" "977" "978" "979" "980"
#> [981] "981" "982" "983" "984" "985" "986" "987" "988" "989" "990"
#> [991] "991" "992" "993" "994" "995" "996" "997" "998" "999" "1000"
#> [1001] "1001" "1002" "1003" "1004" "1005" "1006" "1007" "1008" "1009" "1010"
#> [1011] "1011" "1012" "1013" "1014" "1015" "1016" "1017" "1018" "1019" "1020"
#> [1021] "1021" "1022" "1023" "1024" "1025" "1026" "1027" "1028" "1029" "1030"
#> [1031] "1031" "1032" "1033" "1034" "1035" "1036" "1037" "1038" "1039" "1040"
#> [1041] "1041" "1042" "1043" "1044" "1045" "1046" "1047" "1048" "1049" "1050"
#> [1051] "1051" "1052" "1053" "1054" "1055" "1056" "1057" "1058" "1059" "1060"
#> [1061] "1061" "1062" "1063" "1064" "1065" "1066" "1067" "1068" "1069" "1070"
#> [1071] "1071" "1072" "1073" "1074" "1075" "1076" "1077" "1078" "1079" "1080"
#> [1081] "1081" "1082" "1083" "1084" "1085" "1086" "1087" "1088" "1089" "1090"
#> [1091] "1091" "1092" "1093" "1094" "1095" "1096" "1097" "1098" "1099" "1100"
#> [1101] "1101" "1102" "1103" "1104" "1105" "1106" "1107" "1108" "1109" "1110"
#> [1111] "1111" "1112" "1113" "1114" "1115" "1116" "1117" "1118" "1119" "1120"
#> [1121] "1121" "1122" "1123" "1124" "1125" "1126" "1127" "1128" "1129" "1130"
#> [1131] "1131" "1132" "1133" "1134" "1135" "1136" "1137" "1138" "1139" "1140"
#> [1141] "1141" "1142" "1143" "1144" "1145" "1146" "1147" "1148" "1149" "1150"
#> [1151] "1151" "1152" "1153" "1154" "1155" "1156" "1157" "1158" "1159" "1160"
#> [1161] "1161" "1162" "1163" "1164" "1165" "1166" "1167" "1168" "1169" "1170"
#> [1171] "1171" "1172" "1173" "1174" "1175" "1176" "1177" "1178" "1179" "1180"
#> [1181] "1181" "1182" "1183" "1184" "1185" "1186" "1187" "1188" "1189" "1190"
#> [1191] "1191" "1192" "1193" "1194" "1195" "1196" "1197" "1198" "1199" "1200"
#> [1201] "1201" "1202" "1203" "1204" "1205" "1206" "1207" "1208" "1209" "1210"
#> [1211] "1211" "1212" "1213" "1214" "1215" "1216" "1217" "1218" "1219" "1220"
#> [1221] "1221" "1222" "1223" "1224" "1225" "1226" "1227" "1228" "1229" "1230"
#> [1231] "1231" "1232" "1233" "1234" "1235" "1236" "1237" "1238" "1239" "1240"
#> [1241] "1241" "1242" "1243" "1244" "1245" "1246" "1247" "1248" "1249" "1250"
#> [1251] "1251" "1252" "1253" "1254" "1255" "1256" "1257" "1258" "1259" "1260"
#> [1261] "1261" "1262" "1263" "1264" "1265" "1266" "1267" "1268" "1269" "1270"
#> [1271] "1271" "1272" "1273" "1274" "1275" "1276" "1277" "1278" "1279" "1280"
#> [1281] "1281" "1282" "1283" "1284" "1285" "1286" "1287" "1288" "1289" "1290"
#> [1291] "1291" "1292" "1293" "1294" "1295" "1296" "1297" "1298" "1299" "1300"
#> [1301] "1301" "1302" "1303" "1304" "1305" "1306" "1307" "1308" "1309" "1310"
#> [1311] "1311" "1312" "1313" "1314" "1315" "1316" "1317" "1318" "1319" "1320"
#> [1321] "1321" "1322" "1323" "1324" "1325" "1326" "1327" "1328" "1329" "1330"
#> [1331] "1331" "1332" "1333" "1334" "1335" "1336" "1337" "1338" "1339" "1340"
#> [1341] "1341" "1342" "1343" "1344" "1345" "1346" "1347" "1348" "1349" "1350"
#> [1351] "1351" "1352" "1353" "1354" "1355" "1356" "1357" "1358" "1359" "1360"
#> [1361] "1361" "1362" "1363" "1364" "1365" "1366" "1367" "1368" "1369" "1370"
#> [1371] "1371" "1372" "1373" "1374" "1375" "1376" "1377" "1378" "1379" "1380"
#> [1381] "1381" "1382" "1383" "1384" "1385" "1386" "1387" "1388" "1389" "1390"
#> [1391] "1391" "1392" "1393" "1394" "1395" "1396" "1397" "1398" "1399" "1400"
#> [1401] "1401" "1402" "1403" "1404" "1405" "1406" "1407" "1408" "1409" "1410"
#> [1411] "1411" "1412" "1413" "1414" "1415" "1416" "1417" "1418" "1419" "1420"
#> [1421] "1421" "1422" "1423" "1424" "1425" "1426" "1427" "1428" "1429" "1430"
#> [1431] "1431" "1432" "1433" "1434" "1435" "1436" "1437" "1438" "1439" "1440"
#> [1441] "1441" "1442" "1443" "1444" "1445" "1446" "1447" "1448" "1449" "1450"
#> [1451] "1451" "1452" "1453" "1454" "1455" "1456" "1457" "1458" "1459" "1460"
#> [1461] "1461" "1462" "1463" "1464" "1465" "1466" "1467" "1468" "1469" "1470"
#> [1471] "1471" "1472" "1473" "1474" "1475" "1476" "1477" "1478" "1479" "1480"
#> [1481] "1481" "1482" "1483" "1484" "1485" "1486" "1487" "1488" "1489" "1490"
#> [1491] "1491" "1492" "1493" "1494" "1495" "1496" "1497" "1498" "1499" "1500"
#> [1501] "1501" "1502" "1503" "1504" "1505" "1506" "1507" "1508" "1509" "1510"
#> [1511] "1511" "1512" "1513" "1514" "1515" "1516" "1517" "1518" "1519" "1520"
#> [1521] "1521" "1522" "1523" "1524" "1525" "1526" "1527" "1528" "1529" "1530"
#> [1531] "1531" "1532" "1533" "1534" "1535" "1536" "1537" "1538" "1539" "1540"
#> [1541] "1541" "1542" "1543" "1544" "1545" "1546" "1547" "1548" "1549" "1550"
#> [1551] "1551" "1552" "1553" "1554" "1555" "1556" "1557" "1558" "1559" "1560"
#> [1561] "1561" "1562" "1563" "1564" "1565" "1566" "1567" "1568" "1569" "1570"
#> [1571] "1571" "1572" "1573" "1574" "1575" "1576" "1577" "1578" "1579" "1580"
#> [1581] "1581" "1582" "1583" "1584" "1585" "1586" "1587" "1588" "1589" "1590"
#> [1591] "1591" "1592" "1593" "1594" "1595" "1596" "1597" "1598" "1599" "1600"
#> [1601] "1601" "1602" "1603" "1604" "1605" "1606" "1607" "1608" "1609" "1610"
#> [1611] "1611" "1612" "1613" "1614" "1615" "1616" "1617" "1618" "1619" "1620"
#> [1621] "1621" "1622" "1623" "1624" "1625" "1626" "1627" "1628" "1629" "1630"
#> [1631] "1631" "1632" "1633" "1634" "1635" "1636" "1637" "1638" "1639" "1640"
#> [1641] "1641" "1642" "1643" "1644" "1645" "1646" "1647" "1648" "1649" "1650"
#> [1651] "1651" "1652" "1653" "1654" "1655" "1656" "1657" "1658" "1659" "1660"
#> [1661] "1661" "1662" "1663" "1664" "1665" "1666" "1667" "1668" "1669" "1670"
#> [1671] "1671" "1672" "1673" "1674" "1675" "1676" "1677" "1678" "1679" "1680"
#> [1681] "1681" "1682" "1683" "1684" "1685" "1686" "1687" "1688" "1689" "1690"
#> [1691] "1691" "1692" "1693" "1694" "1695" "1696" "1697" "1698" "1699" "1700"
#> [1701] "1701" "1702" "1703" "1704" "1705" "1706" "1707" "1708" "1709" "1710"
#> [1711] "1711" "1712" "1713" "1714" "1715" "1716" "1717" "1718" "1719" "1720"
#> [1721] "1721" "1722" "1723" "1724" "1725" "1726" "1727" "1728" "1729" "1730"
#> [1731] "1731" "1732" "1733" "1734" "1735" "1736" "1737" "1738" "1739" "1740"
#> [1741] "1741" "1742" "1743" "1744" "1745" "1746" "1747" "1748" "1749" "1750"
#> [1751] "1751" "1752" "1753" "1754" "1755" "1756" "1757" "1758" "1759" "1760"
#> [1761] "1761" "1762" "1763" "1764" "1765" "1766" "1767" "1768" "1769" "1770"
#> [1771] "1771" "1772" "1773" "1774" "1775" "1776" "1777" "1778" "1779" "1780"
#> [1781] "1781" "1782" "1783" "1784" "1785" "1786" "1787" "1788" "1789" "1790"
#> [1791] "1791" "1792" "1793" "1794" "1795" "1796" "1797" "1798" "1799" "1800"
#> [1801] "1801" "1802" "1803" "1804" "1805" "1806" "1807" "1808" "1809" "1810"
#> [1811] "1811" "1812" "1813" "1814" "1815" "1816" "1817" "1818" "1819" "1820"
#> [1821] "1821" "1822" "1823" "1824" "1825" "1826" "1827" "1828" "1829" "1830"
#> [1831] "1831" "1832" "1833" "1834" "1835" "1836" "1837" "1838" "1839" "1840"
#> [1841] "1841" "1842" "1843" "1844" "1845" "1846" "1847" "1848" "1849" "1850"
#> [1851] "1851" "1852" "1853" "1854" "1855" "1856" "1857" "1858" "1859" "1860"
#> [1861] "1861" "1862" "1863" "1864" "1865" "1866" "1867" "1868" "1869" "1870"
#> [1871] "1871" "1872" "1873" "1874" "1875" "1876" "1877" "1878" "1879" "1880"
#> [1881] "1881" "1882" "1883" "1884" "1885" "1886" "1887" "1888" "1889" "1890"
#> [1891] "1891" "1892" "1893" "1894" "1895" "1896" "1897" "1898" "1899" "1900"
#> [1901] "1901" "1902" "1903" "1904" "1905" "1906" "1907" "1908" "1909" "1910"
#> [1911] "1911" "1912" "1913" "1914" "1915" "1916" "1917" "1918" "1919" "1920"
#> [1921] "1921" "1922" "1923" "1924" "1925" "1926" "1927" "1928" "1929" "1930"
#> [1931] "1931" "1932" "1933" "1934" "1935" "1936" "1937" "1938" "1939" "1940"
#> [1941] "1941" "1942" "1943" "1944" "1945" "1946" "1947" "1948" "1949" "1950"
#> [1951] "1951" "1952" "1953" "1954" "1955" "1956" "1957" "1958" "1959" "1960"
#> [1961] "1961" "1962" "1963" "1964" "1965" "1966" "1967" "1968" "1969" "1970"
#> [1971] "1971" "1972" "1973" "1974" "1975" "1976" "1977" "1978" "1979" "1980"
#> [1981] "1981" "1982" "1983" "1984" "1985" "1986" "1987" "1988" "1989" "1990"
#> [1991] "1991" "1992" "1993" "1994" "1995" "1996" "1997" "1998" "1999" "2000"
#>
#> $chain
#> [1] "1" "2" "3"
#>
#> $variable
#> [1] "b_t0C_Intercept" "b_t0W_Intercept"
#> [3] "b_KC_Intercept" "b_KW_Intercept"
#> [5] "b_LinfC_Intercept" "b_LinfW_Intercept"
#> [7] "sd_birth_year__KC_Intercept" "sd_birth_year__KW_Intercept"
#> [9] "sd_birth_year__LinfC_Intercept" "sd_birth_year__LinfW_Intercept"
#> [11] "sigma" "nu"
#> [13] "r_birth_year__KC[1981,Intercept]" "r_birth_year__KC[1982,Intercept]"
#> [15] "r_birth_year__KC[1983,Intercept]" "r_birth_year__KC[1984,Intercept]"
#> [17] "r_birth_year__KC[1985,Intercept]" "r_birth_year__KC[1986,Intercept]"
#> [19] "r_birth_year__KC[1987,Intercept]" "r_birth_year__KC[1988,Intercept]"
#> [21] "r_birth_year__KC[1989,Intercept]" "r_birth_year__KC[1990,Intercept]"
#> [23] "r_birth_year__KC[1991,Intercept]" "r_birth_year__KC[1992,Intercept]"
#> [25] "r_birth_year__KC[1993,Intercept]" "r_birth_year__KC[1994,Intercept]"
#> [27] "r_birth_year__KC[1995,Intercept]" "r_birth_year__KC[1996,Intercept]"
#> [29] "r_birth_year__KC[1997,Intercept]" "r_birth_year__KW[1981,Intercept]"
#> [31] "r_birth_year__KW[1982,Intercept]" "r_birth_year__KW[1983,Intercept]"
#> [33] "r_birth_year__KW[1984,Intercept]" "r_birth_year__KW[1985,Intercept]"
#> [35] "r_birth_year__KW[1986,Intercept]" "r_birth_year__KW[1987,Intercept]"
#> [37] "r_birth_year__KW[1988,Intercept]" "r_birth_year__KW[1989,Intercept]"
#> [39] "r_birth_year__KW[1990,Intercept]" "r_birth_year__KW[1991,Intercept]"
#> [41] "r_birth_year__KW[1992,Intercept]" "r_birth_year__KW[1993,Intercept]"
#> [43] "r_birth_year__KW[1994,Intercept]" "r_birth_year__KW[1995,Intercept]"
#> [45] "r_birth_year__KW[1996,Intercept]" "r_birth_year__KW[1997,Intercept]"
#> [47] "r_birth_year__LinfC[1981,Intercept]" "r_birth_year__LinfC[1982,Intercept]"
#> [49] "r_birth_year__LinfC[1983,Intercept]" "r_birth_year__LinfC[1984,Intercept]"
#> [51] "r_birth_year__LinfC[1985,Intercept]" "r_birth_year__LinfC[1986,Intercept]"
#> [53] "r_birth_year__LinfC[1987,Intercept]" "r_birth_year__LinfC[1988,Intercept]"
#> [55] "r_birth_year__LinfC[1989,Intercept]" "r_birth_year__LinfC[1990,Intercept]"
#> [57] "r_birth_year__LinfC[1991,Intercept]" "r_birth_year__LinfC[1992,Intercept]"
#> [59] "r_birth_year__LinfC[1993,Intercept]" "r_birth_year__LinfC[1994,Intercept]"
#> [61] "r_birth_year__LinfC[1995,Intercept]" "r_birth_year__LinfC[1996,Intercept]"
#> [63] "r_birth_year__LinfC[1997,Intercept]" "r_birth_year__LinfW[1981,Intercept]"
#> [65] "r_birth_year__LinfW[1982,Intercept]" "r_birth_year__LinfW[1983,Intercept]"
#> [67] "r_birth_year__LinfW[1984,Intercept]" "r_birth_year__LinfW[1985,Intercept]"
#> [69] "r_birth_year__LinfW[1986,Intercept]" "r_birth_year__LinfW[1987,Intercept]"
#> [71] "r_birth_year__LinfW[1988,Intercept]" "r_birth_year__LinfW[1989,Intercept]"
#> [73] "r_birth_year__LinfW[1990,Intercept]" "r_birth_year__LinfW[1991,Intercept]"
#> [75] "r_birth_year__LinfW[1992,Intercept]" "r_birth_year__LinfW[1993,Intercept]"
#> [77] "r_birth_year__LinfW[1994,Intercept]" "r_birth_year__LinfW[1995,Intercept]"
#> [79] "r_birth_year__LinfW[1996,Intercept]" "r_birth_year__LinfW[1997,Intercept]"
#> [81] "lprior" "lp__"
d1 <- mcmc_trace(posterior,
pars = c("b_t0C_Intercept", "b_t0W_Intercept", "b_KC_Intercept",
"b_KW_Intercept", "b_LinfC_Intercept", "b_LinfW_Intercept",
"sd_birth_year__KC_Intercept", "sd_birth_year__KW_Intercept",
"sd_birth_year__LinfC_Intercept", "sd_birth_year__LinfW_Intercept",
"sigma", "nu"),
facet_args = list(ncol = 3, strip.position = "left")) +
theme(text = element_text(size = 12),
strip.text = element_text(size = 4),
legend.position = "top") +
scale_color_manual(values = alpha(pal_diag, alpha = 0.8))
#> Scale for 'colour' is already present. Adding another scale for 'colour',
#> which will replace the existing scale.
# Resid vs fitted
d2 <- d %>%
add_residual_draws(m1) %>%
ggplot(aes(x = .row, y = .residual)) +
stat_pointinterval(alpha = 0.5, size = 0.7) +
theme(text = element_text(size = 12))
# qq-plot
# d3 <- d %>%
# add_residual_draws(m1) %>%
# median_qi() %>%
# ggplot(aes(sample = .residual)) +
# geom_qq_line() +
# geom_qq(alpha = 0.8) +
# theme(text = element_text(size = 12))
# Student QQ plot
# https://stackoverflow.com/questions/42493048/computation-failed-for-stat-summary-what-must-be-a-character-string-or-a-func
# https://www.seascapemodels.org/rstats/2017/10/06/qqplot-non-normal-glm.html
summary(m1)$spec_pars # Extract "fixed" effects from m1 for plotting the equation
nu <- summary(m1)$spec_pars[2, 1]
nu
#> [1] 11.75294
# "Base" version
# t <- d_dummy %>%
# add_residual_draws(m3s) %>%
# median_qi()
# resids <- t$.residual
# n <- nrow(d_dummy)
# qqplot(qt(ppoints(n), df = nu), resids,
# xlab = "Theoretical quantile", ylab = "residuals")
# qqline(resids, lty = 2)
# Below ggplot version (check they are the same!)
#?geom_qq_line. Does not take a df argument but dparams, a bit strange
# https://ggplot2.tidyverse.org/reference/geom_qq.html
d3 <- d %>%
add_residual_draws(m1) %>%
median_qi() %>%
ggplot(aes(sample = .residual)) +
geom_qq_line(distribution = qt, dparams = nu) +
geom_qq(alpha = 0.8, distribution = qt, dparams = nu) +
theme(text = element_text(size = 12))
# Posterior predictive
d4 <- pp_check(m1) +
theme(text = element_text(size = 12),
legend.position = c(0.15, 0.95),
legend.background = element_rect(fill = NA)) +
scale_color_manual(values = rev(pal_diag)) +
labs(color = "", x = "log(length [cm])")
#> Using 10 posterior draws for ppc type 'dens_overlay' by default.
#> Scale for 'colour' is already present. Adding another scale for 'colour',
#> which will replace the existing scale.
d1 / (d2 / (d3 + d4)) +
plot_annotation(tag_levels = 'A')

ggsave("figures/supp/vbge_diag_fit.pdf", width = 20, height = 20, unit = "cm")
Supporting analysis
Here I remove cohorts 95-97, since they are a bit extreme and we are
unsure this reflects a true “jump” in L_inf.
M1: All parameters specific by area
# These inits where found after initial exploration
d_supp <- d %>% filter(birth_year < 1995)
#> filter: removed 1,286 rows (17%), 6,148 rows remaining
start_time <- Sys.time()
m1_supp <-
brm(
bf(log(length_cm) ~ areaW*log(LinfW*(1-exp(-KW*(age-t0W)))) + areaC*log(LinfC*(1-exp(-KC*(age-t0C)))),
t0C ~ 1,
t0W ~ 1,
KC ~ 1 + (1|birth_year), # parameter varying by birth_year
KW ~ 1 + (1|birth_year), # parameter varying by birth_year
LinfC ~ 1 + (1|birth_year), # parameter varying by birth_year
LinfW ~ 1 + (1|birth_year), # parameter varying by birth_year
nl = TRUE),
data = d_supp,
family = student(), prior = prior, seed = 9,
iter = 4000, thin = 1, cores = 3, chains = 3, inits = inits_3_chain,
control = list(max_treedepth = 13, adapt_delta = 0.99))
#> Warning: Argument 'inits' is deprecated. Please use argument 'init' instead.
#> Compiling Stan program...
#> Start sampling
end_time <- Sys.time()
end_time - start_time
#> Time difference of 7.796208 hours
# Time difference of 4.624257 hours
summary(m1)
#> Family: student
#> Links: mu = identity; sigma = identity; nu = identity
#> Formula: log(length_cm) ~ areaW * log(LinfW * (1 - exp(-KW * (age - t0W)))) + areaC * log(LinfC * (1 - exp(-KC * (age - t0C))))
#> t0C ~ 1
#> t0W ~ 1
#> KC ~ 1 + (1 | birth_year)
#> KW ~ 1 + (1 | birth_year)
#> LinfC ~ 1 + (1 | birth_year)
#> LinfW ~ 1 + (1 | birth_year)
#> Data: d (Number of observations: 7434)
#> Draws: 3 chains, each with iter = 4000; warmup = 2000; thin = 1;
#> total post-warmup draws = 6000
#>
#> Group-Level Effects:
#> ~birth_year (Number of levels: 17)
#> Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
#> sd(KC_Intercept) 0.04 0.01 0.03 0.07 1.00 2059 3465
#> sd(KW_Intercept) 0.08 0.02 0.05 0.12 1.00 2022 3364
#> sd(LinfC_Intercept) 6.82 1.47 4.48 10.20 1.00 2093 3257
#> sd(LinfW_Intercept) 19.03 5.22 11.15 31.93 1.00 1618 3198
#>
#> Population-Level Effects:
#> Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
#> t0C_Intercept -0.44 0.06 -0.56 -0.33 1.00 6143 4528
#> t0W_Intercept -0.16 0.03 -0.21 -0.11 1.00 7499 4305
#> KC_Intercept 0.15 0.01 0.12 0.17 1.00 1832 3269
#> KW_Intercept 0.19 0.02 0.15 0.23 1.00 1444 2365
#> LinfC_Intercept 39.38 2.09 35.55 43.76 1.00 2043 2797
#> LinfW_Intercept 45.86 5.10 36.57 56.95 1.00 1093 2245
#>
#> Family Specific Parameters:
#> Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
#> sigma 0.11 0.00 0.11 0.11 1.00 6356 4352
#> nu 11.75 1.68 9.02 15.59 1.00 6632 4659
#>
#> Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
#> and Tail_ESS are effective sample size measures, and Rhat is the potential
#> scale reduction factor on split chains (at convergence, Rhat = 1).
summary(m1_supp)
#> Family: student
#> Links: mu = identity; sigma = identity; nu = identity
#> Formula: log(length_cm) ~ areaW * log(LinfW * (1 - exp(-KW * (age - t0W)))) + areaC * log(LinfC * (1 - exp(-KC * (age - t0C))))
#> t0C ~ 1
#> t0W ~ 1
#> KC ~ 1 + (1 | birth_year)
#> KW ~ 1 + (1 | birth_year)
#> LinfC ~ 1 + (1 | birth_year)
#> LinfW ~ 1 + (1 | birth_year)
#> Data: d_supp (Number of observations: 6148)
#> Draws: 3 chains, each with iter = 4000; warmup = 2000; thin = 1;
#> total post-warmup draws = 6000
#>
#> Group-Level Effects:
#> ~birth_year (Number of levels: 14)
#> Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
#> sd(KC_Intercept) 0.05 0.01 0.03 0.07 1.00 2297 3818
#> sd(KW_Intercept) 0.05 0.01 0.03 0.07 1.00 2173 3144
#> sd(LinfC_Intercept) 5.90 1.30 3.90 8.95 1.00 3142 4104
#> sd(LinfW_Intercept) 4.82 1.32 2.75 8.00 1.00 2787 3823
#>
#> Population-Level Effects:
#> Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
#> t0C_Intercept -0.43 0.06 -0.55 -0.31 1.00 7408 4546
#> t0W_Intercept -0.29 0.03 -0.36 -0.22 1.00 7190 4909
#> KC_Intercept 0.15 0.01 0.13 0.18 1.00 2159 3427
#> KW_Intercept 0.19 0.02 0.16 0.22 1.00 2812 3376
#> LinfC_Intercept 37.42 1.86 33.91 41.27 1.00 2410 3495
#> LinfW_Intercept 39.81 1.77 36.55 43.55 1.00 3541 3934
#>
#> Family Specific Parameters:
#> Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
#> sigma 0.11 0.00 0.10 0.11 1.00 6780 4273
#> nu 11.75 1.83 8.89 15.97 1.00 6615 4136
#>
#> Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
#> and Tail_ESS are effective sample size measures, and Rhat is the potential
#> scale reduction factor on split chains (at convergence, Rhat = 1).
plot(m1_supp)



# Save model object to not have to rerun it...
#saveRDS(m1_supp, "output/vbge/m1_supp.rds")
# m1_supp <- readRDS("output/vbge/m1_supp.rds")
# > prior_summary(m1_supp)
# http://mjskay.github.io/tidybayes/articles/tidy-brms.html
# Plot % difference by age class
fm_preds_full <- d %>%
data_grid(age = seq_range(age, by = 1),
area = c("FM")) %>%
mutate(areaC = ifelse(area == "FM", 1, 0),
areaW = ifelse(area == "BT", 1, 0)) %>%
add_epred_draws(m1, re_formula = NA, seed = 5) %>%
ungroup() %>%
rename(FM_pred = .epred) %>%
dplyr::select(-area, -areaC, -areaW)
#> mutate: new variable 'areaC' (double) with one unique value and 0% NA
#> new variable 'areaW' (double) with one unique value and 0% NA
#> ungroup: no grouping variables
#> rename: renamed one variable (FM_pred)
fm_preds_supp <- d %>%
data_grid(age = seq_range(age, by = 1),
area = c("FM")) %>%
mutate(areaC = ifelse(area == "FM", 1, 0),
areaW = ifelse(area == "BT", 1, 0)) %>%
add_epred_draws(m1_supp, re_formula = NA, seed = 5) %>%
ungroup() %>%
rename(FM_pred = .epred) %>%
dplyr::select(-area, -areaC, -areaW)
#> mutate: new variable 'areaC' (double) with one unique value and 0% NA
#> new variable 'areaW' (double) with one unique value and 0% NA
#> ungroup: no grouping variables
#> rename: renamed one variable (FM_pred)
bt_preds_full <- d %>%
data_grid(age = seq_range(age, by = 1),
area = c("BT")) %>%
mutate(areaC = ifelse(area == "FM", 1, 0),
areaW = ifelse(area == "BT", 1, 0)) %>%
add_epred_draws(m1, re_formula = NA, seed = 5) %>%
ungroup() %>%
rename(BT_pred = .epred) %>%
dplyr::select(-area, -areaC, -areaW)
#> mutate: new variable 'areaC' (double) with one unique value and 0% NA
#> new variable 'areaW' (double) with one unique value and 0% NA
#> ungroup: no grouping variables
#> rename: renamed one variable (BT_pred)
bt_preds_supp <- d %>%
data_grid(age = seq_range(age, by = 1),
area = c("BT")) %>%
mutate(areaC = ifelse(area == "FM", 1, 0),
areaW = ifelse(area == "BT", 1, 0)) %>%
add_epred_draws(m1_supp, re_formula = NA, seed = 5) %>%
ungroup() %>%
rename(BT_pred = .epred) %>%
dplyr::select(-area, -areaC, -areaW)
#> mutate: new variable 'areaC' (double) with one unique value and 0% NA
#> new variable 'areaW' (double) with one unique value and 0% NA
#> ungroup: no grouping variables
#> rename: renamed one variable (BT_pred)
ratio_full <- left_join(fm_preds_full, bt_preds_full) %>%
mutate(heated_ref_ratio = (BT_pred/FM_pred),
model = "Full")
#> Joining, by = c("age", ".row", ".chain", ".iteration", ".draw")
#> left_join: added one column (BT_pred)
#> > rows only in x 0
#> > rows only in y ( 0)
#> > matched rows 54,000
#> > ========
#> > rows total 54,000
#> mutate: new variable 'heated_ref_ratio' (double) with 54,000 unique values and 0% NA
#> new variable 'model' (character) with one unique value and 0% NA
ratio_supp <- left_join(fm_preds_supp, bt_preds_supp) %>%
mutate(heated_ref_ratio = (BT_pred/FM_pred),
model = "Subset")
#> Joining, by = c("age", ".row", ".chain", ".iteration", ".draw")
#> left_join: added one column (BT_pred)
#> > rows only in x 0
#> > rows only in y ( 0)
#> > matched rows 54,000
#> > ========
#> > rows total 54,000
#> mutate: new variable 'heated_ref_ratio' (double) with 54,000 unique values and 0% NA
#> new variable 'model' (character) with one unique value and 0% NA
ratio_df <- bind_rows(ratio_full, ratio_supp)
ratio_df %>%
group_by(age, model) %>%
summarise(mean_ratio = mean(heated_ref_ratio)) %>%
pivot_wider(values_from = mean_ratio, names_from = model)
#> group_by: 2 grouping variables (age, model)
#> summarise: now 18 rows and 3 columns, one group variable remaining (age)
#> pivot_wider: reorganized (model, mean_ratio) into (Full, Subset) [was 18x3, now 9x3]
size_ratio <- ggplot(ratio_df, aes(factor(age), heated_ref_ratio, fill = model, color = model)) +
geom_violin(position = position_dodge(width = 0.6), alpha = 0.8, color = NA) +
scale_fill_brewer(palette = "Dark2") +
scale_color_brewer(palette = "Dark2") +
#geom_pointinterval() +
geom_pointrange(stat = "summary",
fun.min = function(z) { quantile(z,0.25) },
fun.max = function(z) { quantile(z,0.75) },
fun = median, color = "white",
position = position_dodge(width = 0.6),
size = 0.5) +
geom_hline(yintercept = 1, linetype = 2, color = "gray50") +
#coord_cartesian(ylim = c(0.85, 1.35)) +
labs(y = "Heated / Reference size-at-age", x = "Age [yrs]") +
guides(fill = "none", color = "none") +
theme(text = element_text(size = 12), # 12 for word doc
legend.position = c(0.9, 0.9),
legend.spacing.y = unit(0, 'cm'),
legend.key.size = unit(0, "cm"),
legend.title = element_text(size = 10),
legend.text = element_text(size = 10)) +
NULL
size_ratio

# Area diff full model
post_L_inf2 <- m1 %>%
gather_draws(b_LinfC_Intercept, b_LinfW_Intercept) %>%
mutate(param = "L_inf",
model = "Full") %>%
pivot_wider(names_from = .variable, values_from = .value) %>%
mutate(diff = b_LinfW_Intercept - b_LinfC_Intercept) %>%
dplyr::select(diff, model, param)
#> mutate (grouped): new variable 'param' (character) with one unique value and 0% NA
#> new variable 'model' (character) with one unique value and 0% NA
#> pivot_wider: reorganized (.variable, .value) into (b_LinfC_Intercept, b_LinfW_Intercept) [was 12000x7, now 6000x7]
#> mutate: new variable 'diff' (double) with 6,000 unique values and 0% NA
post_L_inf_sens2 <- m1_supp %>%
gather_draws(b_LinfC_Intercept, b_LinfW_Intercept) %>%
mutate(param = "L_inf",
model = "Subset") %>%
pivot_wider(names_from = .variable, values_from = .value) %>%
mutate(diff = b_LinfW_Intercept - b_LinfC_Intercept) %>%
dplyr::select(diff, model, param)
#> mutate (grouped): new variable 'param' (character) with one unique value and 0% NA
#> new variable 'model' (character) with one unique value and 0% NA
#> pivot_wider: reorganized (.variable, .value) into (b_LinfC_Intercept, b_LinfW_Intercept) [was 12000x7, now 6000x7]
#> mutate: new variable 'diff' (double) with 6,000 unique values and 0% NA
post_K2 <- m1 %>%
gather_draws(b_KC_Intercept, b_KW_Intercept) %>%
mutate(param = "K",
model = "Full") %>%
pivot_wider(names_from = .variable, values_from = .value) %>%
mutate(diff = b_KW_Intercept - b_KC_Intercept) %>%
dplyr::select(diff, model, param)
#> mutate (grouped): new variable 'param' (character) with one unique value and 0% NA
#> new variable 'model' (character) with one unique value and 0% NA
#> pivot_wider: reorganized (.variable, .value) into (b_KC_Intercept, b_KW_Intercept) [was 12000x7, now 6000x7]
#> mutate: new variable 'diff' (double) with 6,000 unique values and 0% NA
post_K_sens2 <-
m1_supp %>%
gather_draws(b_KC_Intercept, b_KW_Intercept) %>%
mutate(param = "K",
model = "Subset") %>%
pivot_wider(names_from = .variable, values_from = .value) %>%
mutate(diff = b_KW_Intercept - b_KC_Intercept) %>%
dplyr::select(diff, model, param)
#> mutate (grouped): new variable 'param' (character) with one unique value and 0% NA
#> new variable 'model' (character) with one unique value and 0% NA
#> pivot_wider: reorganized (.variable, .value) into (b_KC_Intercept, b_KW_Intercept) [was 12000x7, now 6000x7]
#> mutate: new variable 'diff' (double) with 6,000 unique values and 0% NA
t <- bind_rows(post_L_inf2, post_L_inf_sens2, post_K2, post_K_sens2)
k <- ggplot(filter(t, param == "K"), aes(diff, fill = model, color = model)) +
stat_halfeye(alpha = 0.5, size = 5, .width = c(0.7)) +
facet_wrap(~param, scales = "free") +
guides(color = "none", alpha = "none",
fill = guide_legend(override.aes = list(linetype = rep(0, 2), shape = rep(NA, 2)))) +
scale_fill_brewer(palette = "Dark2") +
scale_color_brewer(palette = "Dark2") +
labs(x = "Heated-Reference", y = "density", fill = "Model") +
theme(legend.key.size = unit(0.2, "cm"),
legend.background = element_blank(),
aspect.ratio = 1)
#> filter: removed 12,000 rows (50%), 12,000 rows remaining
t_sub <- filter(t, !param == "K") %>% mutate(param = as.factor(param))
#> filter: removed 12,000 rows (50%), 12,000 rows remaining
#> mutate: converted 'param' from character to factor (0 new NA)
levels(t_sub$param) <- c(expression(L[infinity]))
linf <- ggplot(t_sub, aes(diff, fill = model, color = model)) +
stat_halfeye(alpha = 0.5, size = 5, .width = c(0.7)) +
facet_wrap(~param, scales = "free", labeller = label_parsed) +
guides(color = "none", alpha = "none",
fill = guide_legend(override.aes = list(linetype = rep(0, 2), shape = rep(NA, 2)))) +
scale_fill_brewer(palette = "Dark2") +
scale_color_brewer(palette = "Dark2") +
labs(x = "Heated-Reference", y = "density", fill = "Model") +
theme(legend.key.size = unit(0.2, "cm"),
legend.background = element_blank(),
aspect.ratio = 1)
linf

(size_ratio / (k + linf)) + plot_annotation(tag_levels = "A") + plot_layout(guides = "collect") & theme(legend.position = "top")

ggsave("figures/supp/vbge_sensi.pdf", width = 20, height = 20, unit = "cm")
# Now compare differences in estiamtes, not differences in differences
post_L_inf3 <- m1 %>%
gather_draws(b_LinfC_Intercept, b_LinfW_Intercept) %>%
mutate(param = "L_inf") %>%
pivot_wider(names_from = .variable, values_from = .value) %>%
dplyr::select(b_LinfC_Intercept, b_LinfW_Intercept) %>%
rename(full_b_LinfC_Intercept = b_LinfC_Intercept,
full_b_LinfW_Intercept = b_LinfW_Intercept)
#> mutate (grouped): new variable 'param' (character) with one unique value and 0% NA
#> pivot_wider: reorganized (.variable, .value) into (b_LinfC_Intercept, b_LinfW_Intercept) [was 12000x6, now 6000x6]
#> rename: renamed 2 variables (full_b_LinfC_Intercept, full_b_LinfW_Intercept)
post_L_inf_sens3 <- m1_supp %>%
gather_draws(b_LinfC_Intercept, b_LinfW_Intercept) %>%
mutate(param = "L_inf") %>%
pivot_wider(names_from = .variable, values_from = .value) %>%
dplyr::select(b_LinfC_Intercept, b_LinfW_Intercept) %>%
rename(sub_b_LinfC_Intercept = b_LinfC_Intercept,
sub_b_LinfW_Intercept = b_LinfW_Intercept)
#> mutate (grouped): new variable 'param' (character) with one unique value and 0% NA
#> pivot_wider: reorganized (.variable, .value) into (b_LinfC_Intercept, b_LinfW_Intercept) [was 12000x6, now 6000x6]
#> rename: renamed 2 variables (sub_b_LinfC_Intercept, sub_b_LinfW_Intercept)
comp <- bind_cols(post_L_inf3, post_L_inf_sens3)
pal <- brewer.pal(n = 3, name = "Dark2")
ggplot(comp) +
stat_halfeye(aes(full_b_LinfC_Intercept - sub_b_LinfC_Intercept, fill = "Reference", color = "Reference"),
alpha = 0.5, size = 5, .width = c(0.7)) +
stat_halfeye(aes(full_b_LinfW_Intercept - sub_b_LinfW_Intercept, fill = "Heated", color = "Heated"),
alpha = 0.5, size = 5, .width = c(0.7)) +
scale_fill_brewer(palette = "Dark2") +
scale_color_brewer(palette = "Dark2") +
guides(color = "none", alpha = "none",
fill = guide_legend(override.aes = list(linetype = rep(0, 2), shape = rep(NA, 2)))) +
labs(x = expression(paste(~italic(L[infinity]))), y = "density", fill = "Model") +
theme(legend.key.size = unit(0.2, "cm"),
legend.background = element_blank(),
aspect.ratio = 1,
legend.position = c(0.9, 0.9)) +
NULL

ggsave("figures/supp/vbge_sensi2.pdf", width = 20, height = 20, unit = "cm")