Contents

library(cellmig)
library(ggplot2)
library(ggforce)
ggplot2::theme_set(new = theme_bw(base_size = 10))
data("d", package = "cellmig")
str(d)
FALSE 'data.frame': 7560 obs. of  6 variables:
FALSE  $ well    : chr  "1" "1" "1" "1" ...
FALSE  $ plate   : chr  "1" "1" "1" "1" ...
FALSE  $ compound: chr  "C1" "C1" "C1" "C1" ...
FALSE  $ dose    : chr  "D1" "D1" "D1" "D1" ...
FALSE  $ v       : num  21.905 0.535 3.348 5.351 1.194 ...
FALSE  $ offset  : num  1 1 1 1 1 1 1 1 1 1 ...
head(d)
FALSE   well plate compound dose          v offset
FALSE 1    1     1       C1   D1 21.9054754      1
FALSE 2    1     1       C1   D1  0.5351645      1
FALSE 3    1     1       C1   D1  3.3484316      1
FALSE 4    1     1       C1   D1  5.3511913      1
FALSE 5    1     1       C1   D1  1.1942105      1
FALSE 6    1     1       C1   D1 26.7272783      1
ggplot(data = d)+
  facet_wrap(facets = ~paste0("compound=", compound), 
             scales = "free_y", ncol = 2)+
  geom_sina(aes(x = as.factor(dose), col = plate, y = v, group = well), 
            size = 0.5)+
  theme_bw()+
  theme(legend.position = "top",
        strip.text.x = element_text(margin = margin(0.03,0,0.03,0, "cm")))+
  ylab(label = "migration velocity")+
  xlab(label = '')+
  scale_color_grey()+
  guides(color = guide_legend(override.aes = list(size = 3)))+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  scale_y_log10()+
  annotation_logticks(base = 10, sides = "l")

1 Create experimental ``artifact’’ -> merge C2 and C6 to create a bimodal velocity distribution

c6 <- d[d$compound == "C6",]
c2 <- d[d$compound == "C2",]
c6$well <- c2$well
c6$v <- c6$v+20
c6$compound <- "C2"


q <- d[d$compound != "C6",]
q <- rbind(q, c6)
d <- q
ggplot(data = d)+
  facet_wrap(facets = ~paste0("compound=", compound), 
             scales = "free_y", ncol = 2)+
  geom_sina(aes(x = as.factor(dose), col = plate, y = v, group = well), 
            size = 0.5)+
  theme_bw()+
  theme(legend.position = "top",
        strip.text.x = element_text(margin = margin(0.03,0,0.03,0, "cm")))+
  ylab(label = "migration velocity")+
  xlab(label = '')+
  scale_color_grey()+
  guides(color = guide_legend(override.aes = list(size = 3)))+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  scale_y_log10()+
  annotation_logticks(base = 10, sides = "l")

o <- cellmig(x = d,
             control = list(mcmc_warmup = 300,  # Warmup iterations
                            mcmc_steps = 1000,  # Sampling iterations
                            mcmc_chains = 2,    # Number of chains
                            mcmc_cores = 2))    # Parallel cores
ggplot(data = o$posteriors$delta_t) +
  geom_line(aes(x = dose, y = mean, col = compound, group = compound)) +
  geom_point(aes(x = dose, y = mean, col = compound)) +
  geom_errorbar(aes(x = dose, y = mean, ymin = X2.5., ymax = X97.5., 
                    col = compound), width = 0.1) +
  ylab(label = expression("Log-Fold Change ("*delta*")")) +
  xlab("Dose") +
  theme(legend.position = "top")

g <- get_ppc_violins(x = o, wrap = TRUE, ncol = 3)
g + scale_y_log10()

g <- get_ppc_means(x = o)
g

# Plate-specific baseline effects
g_alpha_p <- ggplot(data = o$posteriors$alpha_p) +
  geom_errorbarh(aes(y = plate, x = mean, xmin = X2.5., xmax = X97.5.),
                 height = 0.2) +
  geom_point(aes(y = plate, x = mean)) +
  xlab("Plate Effect (log-scale)")

# Variance parameters (Biological vs Technical)
g_sigma <- ggplot() +
  geom_errorbarh(data = o$posteriors$sigma_bio,
                 aes(y = "Biological (Plate)",
                     x = mean, xmin = X2.5., xmax = X97.5.), height = 0.2) +
  geom_errorbarh(data = o$posteriors$sigma_tech,
                 aes(y = "Technical (Well)",
                     x = mean, xmin = X2.5., xmax = X97.5.), height = 0.2) +
  geom_errorbarh(data = o$posteriors$sigma_delta,
                 aes(y = "Treatment Variation",
                     x = mean, xmin = X2.5., xmax = X97.5.), height = 0.2) +
  geom_point(data = o$posteriors$sigma_bio,
             aes(y = "Biological (Plate)", x = mean)) +
  geom_point(data = o$posteriors$sigma_tech,
             aes(y = "Technical (Well)", x = mean)) +
  geom_point(data = o$posteriors$sigma_delta,
             aes(y = "Treatment Variation", x = mean)) +
  xlab("Standard Deviation")

g_alpha_p | g_sigma

2 Session Info

sessionInfo()
FALSE R version 4.6.1 (2026-06-24)
FALSE Platform: x86_64-pc-linux-gnu
FALSE Running under: Ubuntu 24.04.4 LTS
FALSE 
FALSE Matrix products: default
FALSE BLAS:   /home/biocbuild/bbs-3.24-bioc/R/lib/libRblas.so 
FALSE LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0  LAPACK version 3.12.0
FALSE 
FALSE locale:
FALSE  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
FALSE  [3] LC_TIME=en_GB              LC_COLLATE=C              
FALSE  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
FALSE  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
FALSE  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
FALSE [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
FALSE 
FALSE time zone: America/New_York
FALSE tzcode source: system (glibc)
FALSE 
FALSE attached base packages:
FALSE [1] stats     graphics  grDevices utils     datasets  methods   base     
FALSE 
FALSE other attached packages:
FALSE [1] rstan_2.32.7       StanHeaders_2.39.1 ggforce_0.5.0      ggplot2_4.0.3     
FALSE [5] cellmig_1.3.9      BiocStyle_2.41.0  
FALSE 
FALSE loaded via a namespace (and not attached):
FALSE  [1] ggiraph_0.9.6           tidyselect_1.2.1        dplyr_1.2.1            
FALSE  [4] farver_2.1.2            loo_2.10.1              S7_0.2.2               
FALSE  [7] fastmap_1.2.0           lazyeval_0.2.3          tensorA_0.36.2.1       
FALSE [10] tweenr_2.0.3            fontquiver_0.2.1        digest_0.6.39          
FALSE [13] lifecycle_1.0.5         tidytree_0.4.8          posterior_1.7.0        
FALSE [16] magrittr_2.0.5          compiler_4.6.1          rlang_1.3.0            
FALSE [19] sass_0.4.10             tools_4.6.1             yaml_2.3.12            
FALSE [22] knitr_1.52              labeling_0.4.3          htmlwidgets_1.6.4      
FALSE [25] pkgbuild_1.4.8          curl_8.0.0              plyr_1.8.9             
FALSE [28] RColorBrewer_1.1-3      abind_1.4-8             aplot_0.3.1            
FALSE [31] withr_3.0.3             purrr_1.2.2             grid_4.6.1             
FALSE [34] polyclip_1.10-7         stats4_4.6.1            gdtools_0.5.1          
FALSE [37] inline_0.3.21           scales_1.4.0            MASS_7.3-66            
FALSE [40] tinytex_0.60            dichromat_2.0-1         cli_3.6.6              
FALSE [43] rmarkdown_2.32          treeio_1.37.0           generics_0.1.4         
FALSE [46] otel_0.2.0              RcppParallel_6.2.1      ggtree_4.3.0           
FALSE [49] reshape2_1.4.5          ape_5.8-1               cachem_1.1.0           
FALSE [52] stringr_1.6.0           parallel_4.6.1          ggplotify_0.1.3        
FALSE [55] BiocManager_1.30.27     matrixStats_1.5.0       vctrs_0.7.3            
FALSE [58] yulab.utils_0.2.5       V8_8.2.0                jsonlite_2.0.0         
FALSE [61] fontBitstreamVera_0.1.1 bookdown_0.48           gridGraphics_0.5-1     
FALSE [64] patchwork_1.3.2         magick_2.9.1            systemfonts_1.3.2      
FALSE [67] tidyr_1.3.2             jquerylib_0.1.4         glue_1.8.1             
FALSE [70] codetools_0.2-20        distributional_0.9.0    stringi_1.8.9          
FALSE [73] gtable_0.3.6            QuickJSR_1.11.0         tibble_3.3.1           
FALSE [76] pillar_1.11.1           rappdirs_0.3.4          htmltools_0.5.9        
FALSE [79] R6_2.6.1                evaluate_1.0.5          lattice_0.23-1         
FALSE [82] backports_1.5.1         ggfun_0.2.1             fontLiberation_0.1.0   
FALSE [85] bslib_0.12.0            rstantools_2.7.1        Rcpp_1.1.2             
FALSE [88] checkmate_2.3.4         gridExtra_2.3.1         nlme_3.1-171           
FALSE [91] xfun_0.60               fs_2.1.0                pkgconfig_2.0.3