Date: 2026-04-28

# scDesign3 Quickstart

Dongyuan Song1,2* and Qingyang Wang3**

1Department of Genetics and Genome Sciences, UConn Health, Farmington, CT
2Bioinformatics IDP, University of California, Los Angeles, CA
3Department of Statistics, University of California, Los Angeles, CA

*dongyuansong@ucla.edu
**qw802@g.ucla.edu

#### 28 April 2026

#### Package

scDesign3 1.10.0

    library(scDesign3)
    library(SingleCellExperiment)
    library(ggplot2)
    theme_set(theme_bw())

## 0.1 Introduction

scDesign3 is a unified probabilistic framework that generates realistic in silico high-dimensional single-cell omics data of various cell states, including discrete cell types, continuous trajectories, and spatial locations by learning from real datasets. Since the functions of scDesign3 is very comprehensive, here we only introduce how scDesign3 simulates an scRNA-seq dataset with one continuous developmental trajectory. For more information, please check the Articles on our website: (https://songdongyuan1994.github.io/scDesign3/docs/index.html).

## 0.2 Read in the reference data

The raw data is from the scvelo, which describes pancreatic endocrinogenesis. We pre-select the top 1000 highly variable genes and filter out some cell types to ensure a single trajectory. To save computational time, we only use the top 100 genes.

    #example_sce <- readRDS((url("https://figshare.com/ndownloader/files/40581992")))
    #print(example_sce)
    #example_sce <- example_sce[1:100, ]

    data("example_count", package = "scDesign3")
    data("pseudotime", package = "scDesign3")

    example_sce <- SingleCellExperiment::SingleCellExperiment(assays = list(counts = example_count, logcounts = log1p(example_count)),
      colData = DataFrame(pseudotime = pseudotime))

## 0.3 Simulation

The function `scdesign3()` takes in a `SinglecellExperiment` object with the cell covariates (such as cell types, pseudotime, or spatial coordinates) stored in the `colData` of the `SinglecellExperiment` object.

    set.seed(123)
    example_simu <- scdesign3(
        sce = example_sce,
        assay_use = "counts",
        celltype = NULL,
        pseudotime = "pseudotime",
        spatial = NULL,
        other_covariates = NULL,
        mu_formula = "s(pseudotime, k = 10, bs = 'cr')", # mgcg::gam stype formula input.
        sigma_formula = "1", # If you want your dispersion also varies along pseudotime, use "s(pseudotime, k = 5, bs = 'cr')". This will significantly increase the computational cost.
        family_use = "nb",
        n_cores = 2, # Consider the balance between your ROM and threads.
        usebam = FALSE,
        corr_formula = "1",
        copula = "gaussian",
        DT = TRUE,
        pseudo_obs = FALSE,
        return_model = FALSE,
        nonzerovar = FALSE
      )

The output of `scdesign3()` is a list which includes:

- `new_count`: This is the synthetic count matrix generated by `scdesign3()`.
- `new_covariate`:
  - If the parameter `ncell` is set to a number that is different from the number of cells in the input data, this will be a matrix that has the new cell covariates that are used for generating new data.
  - If the parameter `ncell` is the default value, this will be `NULL`.
- `model_aic`: This is a vector include the genes’ marginal models’ AIC, fitted copula’s AIC, and total AIC, which is the sum of the previous two AIC.
- `model_bic`: This is a vector include the genes’ marginal models’ BIC, fitted copula’s BIC, and total BIC, which is the sum of the previous two BIC.
- `marginal_list`:
  - If the parameter `return_model` is set to `TRUE`, this will be a list which contains the fitted gam or gamlss model for all genes in the input data.
  - If the parameter `return_model` is set to the default value `FALSE`, this will be `NULL`.
- `corr_list`:
  - If the parameter `return_model` is set to `TRUE`, this will be a list which contains the either a correlation matrix (when `copula = "gaussian"`) or the fitted vine copula (when `copula = "vine`) for each user specified correlation groups (based on the parameter `corr_by`).
  - If the parameter `return_model` is set to the default value `FALSE`, this will be `NULL`.

In this example, since we did not change the parameter `ncell`, the synthetic count matrix will have the same dimension as the input count matrix.

    dim(example_simu$new_count)
    #> [1]  100 2087

Then, we can create the `SinglecellExperiment` object using the synthetic count matrix and store the `logcounts` to the input and synthetic `SinglecellExperiment` objects.

    logcounts(example_sce) <- log1p(counts(example_sce))
    simu_sce <- SingleCellExperiment(list(counts = example_simu$new_count), colData = example_simu$new_covariate)
    logcounts(simu_sce) <- log1p(counts(simu_sce))

## 0.4 Visualization

    set.seed(123)
    compare_figure <- plot_reduceddim(ref_sce = example_sce,
                                      sce_list = list(simu_sce),
                                      name_vec = c("Reference", "scDesign3"),
                                      assay_use = "logcounts",
                                      if_plot = TRUE,
                                      color_by = "pseudotime",
                                      n_pc = 20)
    plot(compare_figure$p_umap)

## 0.5 Session information

    sessionInfo()
    #> R version 4.6.0 RC (2026-04-17 r89917)
    #> Platform: x86_64-pc-linux-gnu
    #> Running under: Ubuntu 24.04.4 LTS
    #>
    #> Matrix products: default
    #> BLAS:   /home/biocbuild/bbs-3.23-bioc/R/lib/libRblas.so
    #> LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0  LAPACK version 3.12.0
    #>
    #> locale:
    #>  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
    #>  [3] LC_TIME=en_GB              LC_COLLATE=C
    #>  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
    #>  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
    #>  [9] LC_ADDRESS=C               LC_TELEPHONE=C
    #> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
    #>
    #> time zone: America/New_York
    #> tzcode source: system (glibc)
    #>
    #> attached base packages:
    #> [1] stats4    stats     graphics  grDevices utils     datasets  methods
    #> [8] base
    #>
    #> other attached packages:
    #>  [1] ggplot2_4.0.3               SingleCellExperiment_1.34.0
    #>  [3] SummarizedExperiment_1.42.0 Biobase_2.72.0
    #>  [5] GenomicRanges_1.64.0        Seqinfo_1.2.0
    #>  [7] IRanges_2.46.0              S4Vectors_0.50.0
    #>  [9] BiocGenerics_0.58.0         generics_0.1.4
    #> [11] MatrixGenerics_1.24.0       matrixStats_1.5.0
    #> [13] scDesign3_1.10.0            BiocStyle_2.40.0
    #>
    #> loaded via a namespace (and not attached):
    #>  [1] gtable_0.3.6        xfun_0.57           bslib_0.10.0
    #>  [4] lattice_0.22-9      gamlss_5.5-0        vctrs_0.7.3
    #>  [7] tools_4.6.0         parallel_4.6.0      tibble_3.3.1
    #> [10] pkgconfig_2.0.3     Matrix_1.7-5        RColorBrewer_1.1-3
    #> [13] S7_0.2.2            lifecycle_1.0.5     compiler_4.6.0
    #> [16] farver_2.1.2        htmltools_0.5.9     sass_0.4.10
    #> [19] yaml_2.3.12         pillar_1.11.1       jquerylib_0.1.4
    #> [22] MASS_7.3-65         openssl_2.4.0       cachem_1.1.0
    #> [25] DelayedArray_0.38.0 viridis_0.6.5       abind_1.4-8
    #> [28] mclust_6.1.2        nlme_3.1-169        RSpectra_0.16-2
    #> [31] tidyselect_1.2.1    digest_0.6.39       mvtnorm_1.3-7
    #> [34] dplyr_1.2.1         bookdown_0.46       labeling_0.4.3
    #> [37] splines_4.6.0       gamlss.dist_6.1-1   fastmap_1.2.0
    #> [40] grid_4.6.0          gamlss.data_6.0-7   cli_3.6.6
    #> [43] SparseArray_1.12.0  magrittr_2.0.5      S4Arrays_1.12.0
    #> [46] dichromat_2.0-0.1   survival_3.8-6      withr_3.0.2
    #> [49] scales_1.4.0        rmarkdown_2.31      XVector_0.52.0
    #> [52] otel_0.2.0          umap_0.2.10.0       gridExtra_2.3
    #> [55] reticulate_1.46.0   png_0.1-9           askpass_1.2.1
    #> [58] evaluate_1.0.5      knitr_1.51          viridisLite_0.4.3
    #> [61] irlba_2.3.7         mgcv_1.9-4          rlang_1.2.0
    #> [64] Rcpp_1.1.1-1.1      glue_1.8.1          BiocManager_1.30.27
    #> [67] jsonlite_2.0.0      R6_2.6.1