Calbindin

Analyzing the effect of Condition (Hypoxia vs Normoxia) on Purkinje Cells

Setup
source(here::here("src", "setup.R"), echo = FALSE)

## Since downlit doesn't seem to link packages without an explicit & visible library() call anymore ...

library(here)
library(pipebind)

library(dplyr)
library(tidyr)
library(stringr)
library(purrr)
library(ggplot2)

library(glmmTMB)
library(parameters)
library(insight)
library(performance)
library(DHARMa)
library(emmeans)

library(DT)
library(gt)
library(gtsummary)

## Data

calb_responses <- c("N_CC", "Vol_PC_per_cell")

calb_data <- load_calb_data()

1 Clean Data

Here, we only keep the variables that will be used (either as predictor or response) in the analyses.

2 Number of Purkinje cell bodies (per 250x103 µm3)

2.1 Model fitting & diagnostics

Here, we chose to model N_CC, which are counts, with a Generalized Poisson family (which can handle both over and under-dispersion). We use a random intercept per Mouse to account for pseudo-replication.

N_CC_mod <- glmmTMB(
  N_CC ~ Condition + (1 | Mouse),
  family = genpois("log"),
  data = calb_data$clean,
  REML = TRUE
)

2.1.1 Residual diagnostics

Checking the model’s quality of fit through the behavior of its residuals:

check_model(N_CC_mod, check = c("homogeneity", "qq", "reqq", "pp_check"), detrend = FALSE)

make_acf_plot(N_CC_mod)

# Overdispersion test

       dispersion ratio =   0.935
  Pearson's Chi-Squared = 248.704
                p-value =    0.77

2.1.2 Predictive checks

Checking the model’s quality of fit by emulate Bayesian Posterior Predictive Checks (PPC): we simulate predictions from the model and plot how accurately they match the observed data, or statistics of the observed data:

N_CC_mod_dharma <- simulateResiduals(N_CC_mod, plot = FALSE, n = 300, seed = getOption("seed"))
N_CC_mod_dharma_t <- t(N_CC_mod_dharma$simulatedResponse)
ppc_plots(N_CC_mod, simulations = N_CC_mod_dharma_t, term = "Condition", is_count = FALSE)

ppc_stat_plots(N_CC_mod, simulations = N_CC_mod_dharma_t, term = "Condition")

2.1.3 Potential outliers

According to the fitted model, the following observations are potential outliers:

However, we have already removed the data points we had a biological/theoretical reason to believe to be outliers before fitting our model.

2.2 Model analysis

2.2.1 Model parameters

(parameters(
    N_CC_mod, component = "conditional", effects = "fixed",
    exponentiate = should_exp(N_CC_mod), p_adjust = "none", summary = TRUE, digits = 3
  )
  |> print_html() 
  |> tab_header(title = NULL)
)
Parameter Coefficient SE 95% CI z p
(Intercept) 12.852 0.299 (12.278, 13.452) 109.673 < .001
Condition1 1.024 0.024 (0.978, 1.072) 1.021 0.307
Model: N_CC ~ Condition (268 Observations)
Residual standard deviation: 0.574 (df = 266)
Conditional R2: 0.089; Marginal R2: 0.012

2.2.2 Marginal means

emmeans(N_CC_mod, specs = "Condition", type = "response") |> 
  as.data.frame() |> 
  gt()
Condition response SE df lower.CL upper.CL
N 13.16 0.4342 266 12.33 14.04
IH 12.55 0.4115 266 11.77 13.39
- Confidence level used: 0.95
- Intervals are back-transformed from the log scale

2.2.3 Contrasts

emmeans(N_CC_mod, specs = "Condition", type = "response") |> 
  contrast(method = "pairwise", adjust = "none", infer = TRUE) |> 
  as.data.frame() |> 
  gt()
contrast ratio SE df lower.CL upper.CL null t.ratio p.value
N / IH 1.049 0.04871 266 0.9569 1.149 1 1.021 0.3084
- Confidence level used: 0.95
- Intervals are back-transformed from the log scale
- Tests are performed on the log scale
make_signif_boxplot(N_CC_mod, "Condition")

3 Purkinje marked volume (10-4 µm3) per Purkinje cell

3.1 Model fitting & diagnostics

Here, we chose to model Vol_PC_per_cell, which is a strictly positive continuous measure, with a Gamma family. We use a random intercept per Mouse to account for pseudo-replication.

Vol_PC_mod <- glmmTMB(
  Vol_PC_per_cell ~ Condition + (1 | Mouse),
  family = Gamma("log"),
  data = calb_data$clean,
  REML = TRUE
)

3.1.1 Residual diagnostics

Checking the model’s quality of fit through the behavior of its residuals:

check_model(Vol_PC_mod, check = c("homogeneity", "qq", "reqq", "pp_check"), detrend = FALSE)

make_acf_plot(Vol_PC_mod)

3.1.2 Predictive checks

Checking the model’s quality of fit by emulate Bayesian Posterior Predictive Checks (PPC): we simulate predictions from the model and plot how accurately they match the observed data, or statistics of the observed data:

Vol_PC_mod_dharma <- DHARMa::simulateResiduals(Vol_PC_mod, plot = FALSE, n = 300, seed = getOption("seed"))
Vol_PC_mod_dharma_t <- t(Vol_PC_mod_dharma$simulatedResponse)
ppc_plots(Vol_PC_mod, simulations = Vol_PC_mod_dharma_t, term = "Condition")

ppc_stat_plots(Vol_PC_mod, simulations = Vol_PC_mod_dharma_t, term = "Condition")

3.1.3 Potential outliers

According to the fitted model, the following observations are potential outliers:

However, we have already removed the data points we had a biological/theoretical reason to believe to be outliers before fitting our model.

3.2 Model analysis

3.2.1 Model parameters

(parameters(
    Vol_PC_mod, component = "conditional", effects = "fixed",
    exponentiate = should_exp(Vol_PC_mod), p_adjust = "none", summary = TRUE, digits = 3
  )
  |> print_html() 
  |> tab_header(title = NULL)
)
Parameter Coefficient SE 95% CI z p
(Intercept) 0.125 0.007 (0.111, 0.141) -35.019 < .001
Condition1 0.997 0.059 (0.888, 1.120) -0.050 0.960
Model: Vol_PC_per_cell ~ Condition (268 Observations)
Residual standard deviation: 0.284 (df = 266)
Conditional R2: 0.285; Marginal R2: 7.920e-05

3.2.2 Marginal means

emmeans(Vol_PC_mod, specs = "Condition", type = "response") |> 
  as.data.frame() |> 
  gt()
Condition response SE df lower.CL upper.CL
N 0.1247 0.01049 266 0.1057 0.1472
IH 0.1255 0.01051 266 0.1064 0.1480
- Confidence level used: 0.95
- Intervals are back-transformed from the log scale

3.2.3 Contrasts

emmeans(Vol_PC_mod, specs = "Condition", type = "response") |> 
  contrast(method = "pairwise", adjust = "none", infer = TRUE) |> 
  as.data.frame() |> 
  gt()
contrast ratio SE df lower.CL upper.CL null t.ratio p.value
N / IH 0.994 0.118 266 0.7868 1.256 1 -0.05029 0.9599
- Confidence level used: 0.95
- Intervals are back-transformed from the log scale
- Tests are performed on the log scale
make_signif_boxplot(Vol_PC_mod, "Condition")

Back to top