Experimental treatment with edaravone in a mouse model of spinocerebellar ataxia 1

Analysis of grip strength

Author

Martina Sucha, Simona Benediktova, Filip Tichanek, Jan Jedlicka, Stepan Kapl, Dana Jelinkova, Zdenka Purkartova, Jan Tuma, Jitka Kuncova, Jan Cendelin

This page shows R code for the study Sucha et al. (2023, International Journal of Molecular Science).

Citation:

Sucha M, Benediktova S, Tichanek F, Jedlicka J, Kapl S, Jelinkova D, Purkartova Z, Tuma J, Kuncova J, Cendelin J. Experimental Treatment with Edaravone in a Mouse Model of Spinocerebellar Ataxia 1. International Journal of Molecular Sciences. 2023; 24(13):10689. https://doi.org/10.3390/ijms241310689

GitHub page: https://github.com/filip-tichanek/edaravonSCA1

1 Upload of packages

rm(list = ls())

suppressWarnings(suppressMessages( {
library(brms)
library(beeswarm)
library(vioplot)
library(glmmTMB)
library(car)
library(cowplot)
library(ggplot2)
library(tidyverse)
library(bayesplot)  
  } ) )

2 Data import and wrangling

## import of data
load("source_data/myEnvironment.RData")

## averaging grip strength (4 measuremnts)
behav$grip_strength<-rowSums(behav[,c(47:50)])/4

3 Data exploration

par(mar=c(5,3.5,1,1))
par(mgp=c(1.9,0.7,0))
par(mfrow=c(3,1))
plot(behav$grip_strength~behav$group,las=2,xlab="",
     col=cola) 

plot(behav$grip_strength~behav$group_sex,las=2,xlab="",
     col=cola[c(1,1,2,2,3,3,4,4)]) 

hist(behav$grip_strength, 20)

Males may have generally larger strength. Spread seems to be larger for larger values.

4 Modelling

We will fit two gamma models, one with sex as a covariate

4.1 Prior specification

behav$group<-relevel(behav$group,ref='ctrl.sca')

log(mean(behav$grip_strength))
[1] -0.1267686
sd(log(behav$grip_strength))*5
[1] 1.582227

Setting priors

prior01 <- c(set_prior("student_t(3,-0.13,1.6)", class = "b", coef = "Intercept"),
             set_prior("normal(0,2)", class = "b", coef = "groupctrl.wt"),
             set_prior("normal(0,2)", class = "b", coef = "groupeda.wt"),
             set_prior("normal(0,1.2)"  , class = "b", coef = "groupeda.sca"))

prior02 <- c(set_prior("student_t(3,-0.13,1.6)", class = "b", coef = "Intercept"),
             set_prior("normal(0,2)", class = "b", coef = "groupctrl.wt"),
             set_prior("normal(0,2)", class = "b", coef = "groupeda.wt"),
             set_prior("normal(0,1.2)"  , class = "b", coef = "groupeda.sca"),
             set_prior("normal(0,1.2)"    , class = "b", coef = "sex_num"))

4.2 Fitting models and diagnostics

## fitting model without sex
grip_strength_model_01 <- run_model(
              brm(grip_strength ~0+Intercept+group,
                      data=behav, prior = prior01,
                      family=Gamma(link="log"),
                      save_pars = save_pars(all = TRUE),
                      iter=8000, warmup=2000,chains=2,cores=1,seed=17,
                      control = list(adapt_delta = 0.99)),
                  'output/brm/grip_strength_model_01', reuse = TRUE)

## fitting model with 'sex' as a covariate
grip_strength_model_02 <- run_model(
          brm(grip_strength~0+Intercept+group+sex_num,
                      data=behav, prior = prior02,
                      family=Gamma(link="log"),
                      save_pars = save_pars(all = TRUE),
                      iter=8000, warmup=2000,chains=2,cores=1,seed=17,
                      control = list(adapt_delta = 0.99)),
                  'output/brm/grip_strength_model_02', reuse = TRUE)
          

mcmc_trace(grip_strength_model_01)

mcmc_trace(grip_strength_model_02)

summary(grip_strength_model_01)
 Family: gamma 
  Links: mu = log; shape = identity 
Formula: grip_strength ~ 0 + Intercept + group 
   Data: behav (Number of observations: 80) 
  Draws: 2 chains, each with iter = 8000; warmup = 2000; thin = 1;
         total post-warmup draws = 12000

Population-Level Effects: 
             Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
Intercept       -0.25      0.07    -0.38    -0.11 1.00     3857     5146
groupctrl.wt     0.20      0.10     0.01     0.39 1.00     4779     6147
groupeda.wt      0.27      0.10     0.08     0.46 1.00     4374     5682
groupeda.sca    -0.01      0.10    -0.20     0.18 1.00     4623     5893

Family Specific Parameters: 
      Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
shape    11.40      1.81     8.10    15.17 1.00     6682     6444

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(grip_strength_model_02)
 Family: gamma 
  Links: mu = log; shape = identity 
Formula: grip_strength ~ 0 + Intercept + group + sex_num 
   Data: behav (Number of observations: 80) 
  Draws: 2 chains, each with iter = 8000; warmup = 2000; thin = 1;
         total post-warmup draws = 12000

Population-Level Effects: 
             Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
Intercept       -0.25      0.07    -0.38    -0.12 1.00     4298     5795
groupctrl.wt     0.20      0.09     0.01     0.38 1.00     5134     6848
groupeda.wt      0.27      0.09     0.09     0.45 1.00     5119     6744
groupeda.sca    -0.01      0.09    -0.19     0.18 1.00     5217     6836
sex_num          0.14      0.07     0.02     0.27 1.00     8843     8056

Family Specific Parameters: 
      Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
shape    11.94      1.93     8.43    15.98 1.00     7661     6844

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).

Convergence and ESS of both models are OK

4.3 PPC

pla<-pp_check(grip_strength_model_01,type='dens_overlay',ndraws = 50)
plb<-pp_check(grip_strength_model_02,type='dens_overlay',ndraws = 50) 
plot_grid(pla, plb, labels=c("A", "B"), ncol = 1, nrow = 2)

pla<-pp_check(grip_strength_model_01,type='dens_overlay_grouped',ndraws = 50,group='group') 
plb<-pp_check(grip_strength_model_02,type='dens_overlay_grouped',ndraws = 50,group='group') 
plot_grid(pla, plb, labels=c("A", "B"), ncol = 1, nrow = 2)

pla<-pp_check(grip_strength_model_01,type='scatter_avg') 
Using all posterior draws for ppc type 'scatter_avg' by default.
plb<-pp_check(grip_strength_model_02,type='scatter_avg') 
Using all posterior draws for ppc type 'scatter_avg' by default.
plot_grid(pla, plb, labels=c("A", "B"), ncol = 1, nrow = 2)

pp_check(grip_strength_model_01,type='ecdf_overlay',ndraws = 200) 

pp_check(grip_strength_model_02,type='ecdf_overlay',ndraws = 200) 

pla<-pp_check(grip_strength_model_01,type='ecdf_overlay_grouped',ndraws = 50,group='group') 
plb<-pp_check(grip_strength_model_02,type='ecdf_overlay_grouped',ndraws = 50,group='group') 
plot_grid(pla, plb, labels=c("A", "B"), ncol = 1, nrow = 2)

pla<-pp_check(grip_strength_model_01,type="stat_2d", stat = c("max", "min"),ndraws=200)
plb<-pp_check(grip_strength_model_02,type="stat_2d", stat = c("max", "min"),ndraws=200)
plot_grid(pla, plb, labels=c("A", "B"), ncol = 1, nrow = 2)

pla<-pp_check(grip_strength_model_01,type="stat_2d", stat = c("mean", "sd"),ndraws=200)
plb<-pp_check(grip_strength_model_02,type="stat_2d", stat = c("mean", "sd"),ndraws=200)
plot_grid(pla, plb, labels=c("A", "B"), ncol = 1, nrow = 2)

### Are there too influential observations?
par(mfrow=c(1,2))
plot(loo(grip_strength_model_01));loo(grip_strength_model_01)

Computed from 12000 by 80 log-likelihood matrix

         Estimate   SE
elpd_loo     -6.3  6.4
p_loo         4.8  0.8
looic        12.5 12.9
------
Monte Carlo SE of elpd_loo is 0.0.

All Pareto k estimates are good (k < 0.5).
See help('pareto-k-diagnostic') for details.
plot(loo(grip_strength_model_02));loo(grip_strength_model_02)


Computed from 12000 by 80 log-likelihood matrix

         Estimate   SE
elpd_loo     -4.7  6.0
p_loo         5.5  0.8
looic         9.4 11.9
------
Monte Carlo SE of elpd_loo is 0.0.

All Pareto k estimates are good (k < 0.5).
See help('pareto-k-diagnostic') for details.

Both models seem to retrodict the data well

4.4 Leave-one out cross-validation to compare predicitve accuracy of both models

grip_strength_model_01 <- add_criterion(grip_strength_model_01, criterion = "loo")
grip_strength_model_02 <- add_criterion(grip_strength_model_02, criterion = "loo")
loo_compare(grip_strength_model_01,grip_strength_model_02)
                       elpd_diff se_diff
grip_strength_model_02  0.0       0.0   
grip_strength_model_01 -1.6       2.2   

The difference between the models in terms predictive accuracy is minimal and both show basically the same estimates. We will use the 1st (simpler) model

4.5 Extraction of posterior samples

post_fix<-as.data.frame(grip_strength_model_01, variable = c("b_Intercept","b_groupctrl.wt",
                                                       "b_groupeda.wt","b_groupeda.sca"))
names(post_fix)[1]<-"sca_ctrl"

post_fix$wt_ctrl<-post_fix$sca_ctrl+post_fix$b_groupctrl.wt
post_fix$wt_eda<-post_fix$sca_ctrl+post_fix$b_groupeda.wt
post_fix$sca_eda<-post_fix$sca_ctrl+post_fix$b_groupeda.sca
post_fix$wt_contrast<-post_fix$wt_eda-post_fix$wt_ctrl

groupquant<-sapply(post_fix[,c(5,6,1,7)],function(p) quantile(p, probs = c(0.025,0.975,0.5)))
groupquant<-exp(groupquant)

4.6 Data and model visualization

behav$group<-factor(behav$group,levels=c('ctrl.wt','eda.wt','ctrl.sca','eda.sca'))

par(mfrow=c(1,2))
par(mar=c(2,3,0,0))
par(mgp=c(2,0.6,0))
range<-c(0,2);scal<-range[2]-range[1]
xrange<-c(0.5,4.5);xscal=xrange[2]-xrange[1]
plot(NULL,xlim=c(xrange[1],xrange[2]),ylim=c(range[1],range[2]),xlab="",
     ylab="Grip strength",las=1, axes=FALSE,cex.lab=1)

rect(xrange[1],range[2],xrange[2],range[1],col="grey92",border=NA)
x<-range[1]
repeat{
  lines(c(xrange[1],xrange[2]),c(x,x),col="white",lwd=0.7)
  x=x+0.2;if(x>range[2]){break}}

x<-1
repeat{
  lines(c(x,x),c(range[1],range[2]),col="white",lwd=0.7)
  x=x+1;if(x>4.5){break}}

vioplot(behav$grip_strength~behav$group,col=colb,at=c(1:4),add=T,
        border=cola,axes=FALSE,drawRect=F,lwd=1,wex=0.8)

beeswarm(behav$grip_strength~behav$group,col=colc,at=c(1:4),add=T,pwpch=(16.5+behav$sex_num) )

tp<-(groupquant[3,])
xx<-1;wid=0.25
repeat{
  lines(c(xx-wid,xx+wid),c(tp[xx],tp[xx]),lwd=2,col="black");
  lines(c(xx,xx),c(groupquant[1,xx],groupquant[2,xx]),lwd=1.7,col="black")
  xx<-xx+1
  if(xx>4){break}}

tckk=-0.02
axis(2,las=2,cex.axis=1.1,at=seq(range[1],range[2],by=0.4),
     labels=c(rep("",length(seq(range[1],range[2],by=0.4)))),pos=xrange[1],tck=tckk)
axis(2,las=2,cex.axis=1.1,at=seq(range[1],range[2],by=0.4),pos=xrange[1],tck=tckk)

axis(side=1,las=1,cex.axis=1.1,at=c(seq(1,4,by=1)),
     labels=c(rep("",length(seq(1,4,by=1)))),pos=range[1],tck=tckk)
lines(c(xrange[1],xrange[2]),c(range[1],range[1]))
text(c(1:4),c(rep(range[1]-0.046*scal,4)),xpd=T,cex=1.1,col=cola,
     c("Wt","Wt", "SCA1", "SCA1"))
ypo<-c(range[1]-0.1*scal,range[1]-0.1*scal)
text(c(1:4),c(ypo[1],ypo[2],ypo[1],ypo[2]),xpd=T,cex=1.1,col=cola,
     c("0","edv", "0", "edv"))

ypos<-0.3;xpos=1.4
points(xpos,ypos,pch=16,cex=1.4,col=rgb(0.4,0.4,0.4,alpha=0.6))
text(xpos+0.19*xscal,ypos,"Females",col="grey40",cex=1.2)
points(xpos,ypos-0.08*scal,pch=17,cex=1.4,col=rgb(0.4,0.4,0.4,alpha=0.6))
text(xpos+0.19*xscal,ypos-0.08*scal,"Males",col="grey40",cex=1.2)

### probability distributions --------
par(mar=c(2,0,0,0))
dif<-data.frame(post_fix$wt_contrast,post_fix$b_groupeda.sca,
                post_fix$b_groupctrl.wt)
dif<-exp(dif)

yla<-"Fold-difference grip strength"
tckk=-0.018
ste<-seq(0.4,1.6,by=0.2)
mons_poste(dif,1)

zpos=seq(0,1,1/3)
xx=1;ind=0.3;xpol<-0.6
text(xpol+1,zpos[xx]+zpos[2]*ind,
     "Wt: ed x 0 ",cex=1)
xx=xx+1

text(xpol+1,zpos[xx]+zpos[2]*ind,
     "SCA1: ed x 0 ",cex=1)
xx=xx+1

text(xpol+0.2,zpos[xx]+zpos[2]*ind,
     "0: Wt x SCA1",cex=1)