library(knitr)
opts_chunk$set(echo = FALSE)
options(knitr.kable.NA = '')
library(ladybird)
library(tidyverse)
library(plotly)
library(scales)
library(INBOtheme)
dirname(params$models) %>%
  file.path("..") %>%
  list.files(full.names = TRUE, recursive = TRUE) %>%
  map(readRDS) -> base_models
species <- map_chr(base_models, "species")
waic <- map_dbl(base_models, "waic")
map_lgl(base_models, "first_order") %>%
  ifelse(1, 2) -> rw_order
model_type <- map_chr(base_models, "type")
map(base_models, "hyperpar") %>%
  map(rownames_to_column, var = "parameter") %>%
  map2(species, ~mutate(.x, species = .y)) %>%
  map2(rw_order, ~mutate(.x, rw_order = .y)) %>%
  map2(model_type, ~mutate(.x, model = .y)) %>%
  bind_rows() -> hyperpar
map(base_models, "fixed") %>%
  map(rownames_to_column, var = "parameter") %>%
  map2(species, ~mutate(.x, species = .y)) %>%
  map2(rw_order, ~mutate(.x, rw_order = .y)) %>%
  map2(model_type, ~mutate(.x, model = .y)) %>%
  bind_rows() -> fixed
map(base_models, "trend") %>%
  map2(species, ~mutate(.x, species = .y)) %>%
  map2(rw_order, ~mutate(.x, rw_order = .y)) %>%
  map2(model_type, ~mutate(.x, model = .y)) %>%
  bind_rows() %>%
  mutate(
    type = replace_na(type, ""),
    prediction = interaction(model, type, sep = " ")
  ) -> trend
map(base_models, "roc") %>%
  map("ci") %>%
  map(
    ~data.frame(parameter = c("lcl", "estimate", "ucl"), auc = as.vector(.x))
  ) %>%
  map2(species, ~mutate(.x, species = .y)) %>%
  map2(rw_order, ~mutate(.x, rw_order = .y)) %>%
  map2(model_type, ~mutate(.x, model = .y)) %>%
  bind_rows() -> auc

Compare models

base model

$$Y_{tx} \sim \mathcal{Bernoulli(\pi_{tx})}$$

$$\pi_{tx} = \frac{\exp\eta_{tx}}{1 + \exp\eta_{tx}}$$

$$\eta_{tx} = \beta_0 + \beta_ct_c + b_t + \omega_{tx}$$

first order random walk $$b_t - b_{t - 1} \sim \mathcal{N}(0, \sigma^2_r)$$

second order random walk $$(b_{t + 1} - b_t) - (b_t - b_{t - 1}) \sim \mathcal{N}(0, \sigma^2_r)$$

$$\omega_{tx} = \rho\omega_{t-1x} + \xi_{tx}$$

$$\xi_x \sim \mathcal{N}(0, \sigma^2_sC(\Delta_{xy}))$$

$$C(\Delta_{xy}) = \frac{1}{\Gamma(\lambda) 2 ^{\lambda - 1}} (\kappa \Delta_{xy}) ^\lambda K_\lambda (\kappa \Delta_{xy})$$

$$r = \frac{\sqrt{8\lambda}}{\kappa}$$

Using the probability of a secondary species

For know we use only H. axyridis as the secondary species.

We mention only the new parameters and formulas.

$$\eta_{tx} = \beta_0 + \beta_bt_b + \beta_at_a + (1 + \beta_p p_{tx}) b_t + \omega_{tx}$$

Using the cumulative probability of a secondary species

We replace the individual probability with the cumulative probability. This is a proxy for the number of years where a species is present since the start of the dataset.

$$\eta_{tx} = \beta_0 + \beta_bt_b + \beta_at_a + (1 + \beta_p s_{tx}) b_t + \omega_{tx}$$

Comparing fits

data.frame(species, waic, rw_order = rw_order, model = model_type) %>%
  group_by(species) %>%
  mutate(
    waic = waic - min(waic),
    model = interaction(model, rw_order, sep = " ")
  ) %>%
  select(-rw_order) %>%
  arrange(model) %>%
  pivot_wider(names_from = model, values_from = waic) %>%
  kable(
    digits = 1,
    caption = 
  "Difference in WAIC compared to the model with lowest WAIC for each species.
Smaller is better."
  )
auc %>%
  pivot_wider(names_from = parameter, values_from = auc) %>%
  mutate(
    species = reorder(species, estimate),
    order = factor(rw_order)
  ) %>%
  ggplot(
    aes(
      x = estimate, xmin = lcl, xmax = ucl, y = species, colour = model,
      linetype = order, shape = order
    )
  ) +
  geom_errorbarh(position = position_dodge(width = 0.5)) +
  geom_point(position = position_dodge(width = 0.5)) +
  theme(axis.title = element_blank()) +
  ggtitle("AUC")
data.frame(species, waic, rw_order = rw_order, model = model_type) %>%
  group_by(species) %>%
  mutate(
    waic = waic - min(waic)
  ) %>%
  ungroup() %>%
  inner_join(
    auc %>%
      pivot_wider(names_from = parameter, values_from = auc),
    by = c("species", "rw_order", "model")
  ) %>%
  mutate(order = factor(rw_order)) %>%
  ggplot(
    aes(
      x = waic, y = estimate, ymin = lcl, ymax = ucl, colour = model,
      shape = order, linetype = order)
  ) +
  geom_point() +
  geom_errorbar() +
  facet_wrap(~species, scales = "free") +
  scale_x_sqrt() +
  scale_y_continuous("AUC")

Fixed effects

fixed %>%
  filter(parameter == "intercept") %>%
  mutate(
    species = reorder(species, mean),
    median = `0.5quant`,
    lcl = `0.025quant`,
    ucl = `0.975quant`
  ) %>%
  ggplot(aes(x = median, xmin = lcl, xmax = ucl, y = species, colour = model)) +
  geom_errorbarh(position = position_dodge(0.5)) +
  geom_point(position = position_dodge(0.5)) +
  facet_wrap(~rw_order, scales = "free_x") +
  theme(axis.title = element_blank())
fixed %>%
  filter(parameter != "intercept") %>%
  mutate(
    species = reorder(species, mean),
    median = `0.5quant`,
    lcl = `0.025quant`,
    ucl = `0.975quant`
  ) %>%
  ggplot(
    aes(
      x = median, xmin = lcl, xmax = ucl, y = species, colour = model,
      linetype = parameter, shape = parameter
    )
  ) +
  geom_errorbarh(position = position_dodge(0.5)) +
  geom_point(position = position_dodge(0.5)) +
  geom_vline(xintercept = 0, linetype = 2) +
  facet_wrap(~rw_order, scales = "free_x") +
  theme(axis.title = element_blank())

General trends

Panels indicate first and second order random walks

plot_trend <- function(this_species) {
  trend %>%
    filter(species  == this_species, type %in% c("median", "without", "")) %>%
    ggplot(aes(x = year, y = mean, ymin = lcl, ymax = ucl)) +
    geom_ribbon(aes(fill = prediction, colour = prediction), alpha = 0.3, linetype = 3) +
    geom_line(aes(colour = prediction)) +
    scale_y_continuous(labels = percent) +
    theme(axis.title = element_blank()) +
    ggtitle(this_species) +
    facet_wrap(~rw_order, scales = "free_y")
}
plot_trend("Adal_bipu")
plot_trend("Adal_dece")
plot_trend("Calv_dece")
plot_trend("Calv_quat")
plot_trend("Cocc_sept")
plot_trend("Cocc_quin")
plot_trend("Exoc_quad")
plot_trend("Haly_sede")
plot_trend("Harm_axyr")
plot_trend("Harm_quad")
plot_trend("Hipp_vari")
plot_trend("Oeno_cong")
plot_trend("Prop_quat")
plot_trend("Psyl_vigi")
plot_trend("Tytt_sede")

Spatio-temporal fields

hyperpar %>%
  filter(parameter == "Range for site") %>%
  mutate(
    species = reorder(species, mean),
    order = factor(rw_order)
  ) %>%
  ggplot(
    aes(
      x = mean, xmin = `0.025quant`, xmax = `0.975quant`, y = species,
      colour = model, linetype = order, shape = order
    )
  ) +
  geom_errorbarh(position = position_dodge(width = 0.5)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_continuous(limits = c(0, NA)) +
  ggtitle("Range of the spatio-temporal field in km") +
  theme(axis.title = element_blank())
hyperpar %>%
  filter(parameter == "Stdev for site") %>%
  mutate(
    species = reorder(species, mean),
    order = factor(rw_order)
  ) %>%
  ggplot(
    aes(
      x = mean, xmin = `0.025quant`, xmax = `0.975quant`, y = species,
      colour = model, linetype = order, shape = order
    )
  ) +
  geom_errorbarh(position = position_dodge(width = 0.5)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_continuous(limits = c(0, NA)) +
  ggtitle("Stdev of the spatio-temporal field in km") +
  theme(axis.title = element_blank())
hyperpar %>%
  filter(parameter == "GroupRho for site", !is.na(mean)) %>%
  mutate(
    species = reorder(species, mean),
    order = factor(rw_order)
  ) %>%
  ggplot(
    aes(
      x = mean, xmin = `0.025quant`, xmax = `0.975quant`, y = species,
      colour = model, linetype = order, shape = order
    )
  ) +
  geom_errorbarh(position = position_dodge(width = 0.5)) +
  geom_point(position = position_dodge(width = 0.5)) +
  ggtitle("Rho of the spatio-temporal field in km") +
  theme(axis.title = element_blank())

Random walk hyper parameters

hyperpar %>%
  filter(parameter == "Beta for iyear2", !is.na(mean), sd < 1e6) %>%
  mutate(
    species = reorder(species, mean),
    order = factor(rw_order)
  ) %>%
  ggplot(
    aes(
      x = mean, xmin = `0.025quant`, xmax = `0.975quant`, y = species,
      colour = model, linetype = order, shape = order
    )
  ) +
  geom_errorbarh(position = position_dodge(width = 0.5)) +
  geom_point(position = position_dodge(width = 0.5)) +
  ggtitle("Beta for the random walk") +
  theme(axis.title = element_blank())
hyperpar %>%
  filter(parameter == "Precision for iyear", !is.na(mean)) %>%
  mutate(
    species = reorder(species, mean),
    order = factor(rw_order),
    median = 1 / `0.5quant`,
    lcl = 1 / `0.025quant`,
    ucl = 1 / `0.975quant`
  ) %>%
  ggplot(aes(x = median, xmin = lcl, xmax = ucl, y = species)) +
  geom_errorbarh(position = position_dodge(width = 0.5)) +
  geom_point(position = position_dodge(width = 0.5)) +
  ggtitle("Stdev for the random walk") +
  theme(axis.title = element_blank()) +
  facet_wrap(~ rw_order + model, scales = "free_x")
hyperpar %>%
  filter(parameter == "Beta for iyear2", !is.na(mean), sd < 1e6) %>%
  select(
    species, model, rw_order, beta_median = `0.5quant`, beta_lcl = `0.025quant`,
    beta_ucl = `0.975quant`
  ) %>%
  inner_join(
    hyperpar %>%
      filter(parameter == "Precision for iyear", !is.na(mean)) %>%
      transmute(
        species, model, rw_order, sd_median = 1 / sqrt(`0.5quant`),
        sd_lcl = 1 / sqrt(`0.025quant`), sd_ucl = 1 / sqrt(`0.975quant`)
      ),
    by = c("species", "model", "rw_order")
  ) %>%
  mutate(type = interaction(model, rw_order)) %>%
  ggplot(aes(x = beta_median, y = sd_median, colour = type)) +
  geom_point()


inbo/ladybird documentation built on March 14, 2021, 3:47 p.m.