Overview
See the Glossary for term definitions used throughout this project.
- Compares tumor vs normal or baseline vs relapse samples
- Three complementary methods: DESeq2, edgeR, limma-voom
- Consensus genes (significant in all three) used for pathway analysis
- Visualizations: PCA, volcano plot, MA plot, heatmap, method comparison
Note: This vignette was built in CI with sample_limit=20. Local builds default to 200 samples. Numbers below reflect the CI subset.
Method Comparison
Summary of DE genes detected by each method (DESeq2, edgeR, limma-voom) and their consensus overlap.
Generating code
{
if (is.null(de_method_summary) || nrow(de_method_summary) ==
0)
return(NULL)
caption <- paste0("Differential expression results across methods. ",
"Method = DE analysis package. ", "DESeq2: negative binomial GLM with Wald test and apeglm LFC shrinkage. ",
"edgeR: quasi-likelihood F-test with TMM normalization. ",
"limma-voom: linear models with precision weights on log2-CPM. ",
"Genes Tested = number of genes after filtering. ", "Significant = genes with |log2FC| > 1 AND adjusted p-value < 0.05. ",
"Up/Down = direction of fold change (tumor vs normal).")
DT::datatable(de_method_summary, rownames = FALSE, filter = "top",
options = list(pageLength = 10, scrollX = TRUE), colnames = c("Method",
"Genes Tested", "Significant", "Up", "Down"), caption = htmltools::tags$caption(style = "caption-side: top; text-align: left;",
caption))
}
Generating code
{
if (is.null(de_method_summary) || nrow(de_method_summary) ==
0)
return(NULL)
long <- rbind(data.frame(method = de_method_summary$method,
direction = "Up", count = de_method_summary$n_up), data.frame(method = de_method_summary$method,
direction = "Down", count = -de_method_summary$n_down))
ggplot2::ggplot(long, ggplot2::aes(x = method, y = count,
fill = direction)) + ggplot2::geom_col() + ggplot2::scale_fill_manual(values = c(Up = "#DC3545",
Down = "#0066CC"), name = "Direction") + ggplot2::geom_hline(yintercept = 0,
linewidth = 0.3) + ggplot2::labs(title = "DE Genes by Method",
x = NULL, y = "Number of genes (down shown as negative)",
caption = paste0("DESeq2: negative binomial GLM with apeglm shrinkage. ",
"edgeR: quasi-likelihood F-test with TMM normalization. ",
"limma: empirical Bayes moderated t-test with voom weights. ",
"Up (red) = log2FC > 1. Down (blue) = log2FC < -1. ",
"Thresholds: |log2FC| > 1, padj < 0.05. ", "With sample_limit=20, zero significant genes is expected. ",
"Source: DESeq2/edgeR/limma results. ", "See method table for exact counts and annotated DE table for top genes.")) +
theme_commpass_dark() + ggplot2::theme(plot.caption = ggplot2::element_text(size = 7,
hjust = 0, lineheight = 1.2))
}

Principal Component Analysis
- Computed from top 500 most variable genes after VST
- VST stabilizes variance across the expression range
- Preferred over raw counts or logCPM for exploratory visualization

Volcano Plot
- Statistical significance (-log10 adjusted p-value) vs biological effect size (log2 fold change)
- Genes in upper corners are both statistically significant and biologically meaningful

MA Plot
- Bland-Altman plot: mean expression (x-axis) vs fold change (y-axis)
- Reveals whether DE signals concentrate at particular expression levels
- Detects bias in fold-change estimates

Heatmap of Top DE Genes
The heatmap shows Z-score scaled VST expression for the most significant genes. Rows (genes) and columns (samples) are hierarchically clustered.

Consensus Genes
Genes identified as significant by all three methods (DESeq2, edgeR, limma) represent the highest-confidence DE candidates.
60 consensus DE genes found across all three methods.
Top 20 consensus genes (sorted by mean rank): ENSG00000006704.11, ENSG00000027869.12, ENSG00000100065.15, ENSG00000100628.12, ENSG00000104833.12, ENSG00000106025.9, ENSG00000114948.13, ENSG00000127533.4, ENSG00000128283.7, ENSG00000130055.14, ENSG00000131711.15, ENSG00000134533.6, ENSG00000136960.13, ENSG00000138172.11, ENSG00000143341.12, ENSG00000149742.10, ENSG00000154734.16, ENSG00000157214.14, ENSG00000162878.13, ENSG00000163362.11, … (40 more)
These genes are used for pathway analysis via ORA.
Paired Longitudinal DE
For patients with samples at multiple timepoints (baseline and relapse), a paired design (~ patient_id + visit) controls for inter-patient variability and tests for within-patient expression changes over time.
Paired analysis: 2 patients, 4 samples
12 DE genes at padj < 0.05

Annotated DE Results
Gene symbols make Ensembl IDs interpretable. The annotate_genes() function maps Ensembl IDs to HGNC symbols using MSigDB gene mappings.
Generating code
{
if (is.null(de_results_annotated) || nrow(de_results_annotated) ==
0) {
return(NULL)
}
top <- utils::head(de_results_annotated[order(de_results_annotated$padj),
], 15)
display_cols <- intersect(c("gene_symbol", "log2FoldChange",
"baseMean", "padj"), names(top))
if ("log2FoldChange" %in% names(top))
top$log2FoldChange <- round(top$log2FoldChange, 2)
if ("baseMean" %in% names(top))
top$baseMean <- round(top$baseMean, 1)
if ("padj" %in% names(top))
top$padj <- signif(top$padj, 4)
caption <- paste0("Top 15 DE genes by adjusted p-value (DESeq2). ",
"gene_symbol = HGNC symbol mapped from Ensembl IDs via MSigDB. ",
"log2FoldChange = log2 ratio (positive = upregulated in tumor/relapse). ",
"baseMean = mean normalized count across all samples. ",
"padj = Benjamini-Hochberg adjusted p-value. ", "See data dictionary for gene ID details.")
DT::datatable(top[, display_cols], rownames = FALSE, filter = "top",
options = list(pageLength = 15, scrollX = TRUE), caption = htmltools::tags$caption(style = "caption-side: top; text-align: left;",
caption))
}
Pathway Enrichment Visualizations
GSEA Enrichment Dot Plot
Gene Set Enrichment Analysis using the full ranked gene list against MSigDB Hallmark pathways.

ORA Enrichment Bar Plot
Over-representation analysis testing whether consensus DE genes are enriched in specific pathways.

Next Steps
- Pathway analysis: Consensus DE genes are tested for enrichment in MSigDB Hallmark, KEGG, and other collections. See the pathway analysis vignette.
- Survival stratification: DE gene signatures can inform survival analysis. See the survival analysis vignette.
- Cytogenetic context: See the EDA vignette for the cytogenetic landscape underlying these expression changes.
Data Sources
Results in this vignette are derived from the MMRF CoMMpass study (MMRF-COMMPASS, ~1,143 patients), downloaded via TCGAbiolinks. The pipeline runs with a configurable sample_limit (default 200; CI uses 20).
For full citations, data access tiers, and the distinction between pipeline data and synthetic test data, see the Data Sources vignette.
Recent Changes
Recent project commits with lines added, files changed, and change categories.
Reproducibility
Session Info (click to expand)
Show code
sessionInfo()
#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 26.04 LTS
#>
#> Matrix products: default
#> BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so; LAPACK version 3.12.0
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
#> [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: Etc/UTC
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] targets_1.12.0
#>
#> loaded via a namespace (and not attached):
#> [1] base64url_1.4 gtable_0.3.6 jsonlite_2.0.0 dplyr_1.2.1
#> [5] compiler_4.6.1 tidyselect_1.2.1 callr_3.8.0 jquerylib_0.1.4
#> [9] scales_1.4.0 yaml_2.3.12 fastmap_1.2.0 ggplot2_4.0.3
#> [13] R6_2.6.1 labeling_0.4.3 generics_0.1.4 igraph_2.3.3
#> [17] knitr_1.51 htmlwidgets_1.6.4 backports_1.5.1 tibble_3.3.1
#> [21] maketools_1.3.2 RColorBrewer_1.1-3 bslib_0.11.0 pillar_1.11.1
#> [25] rlang_1.3.0 DT_0.34.0 cachem_1.1.0 xfun_0.60
#> [29] sass_0.4.10 sys_3.4.3 S7_0.2.2 otel_0.2.0
#> [33] cli_3.6.6 withr_3.0.3 magrittr_2.0.5 crosstalk_1.2.2
#> [37] ps_1.9.3 grid_4.6.1 digest_0.6.39 processx_3.9.0
#> [41] secretbase_1.3.0 lifecycle_1.0.5 prettyunits_1.2.0 vctrs_0.7.3
#> [45] evaluate_1.0.5 glue_1.8.1 data.table_1.18.4 farver_2.1.2
#> [49] codetools_0.2-20 buildtools_1.0.0 rmarkdown_2.31 tools_4.6.1
#> [53] pkgconfig_2.0.3 htmltools_0.5.9