| Title: | Compositional and Transcriptional Decomposition of Pseudo-Bulk Differential Expression |
|---|---|
| Description: | scCompoundDE decomposes pseudo-bulk differential expression (DE) signals into two orthogonal components: transcriptional changes (cell-intrinsic expression shifts) and compositional changes (shifts in the relative abundance of cell subtypes). Standard pseudo-bulk DE tools confound these two sources of signal, producing spurious DE calls when subtype proportions differ between conditions. scCompoundDE fits per-subtype limma-voom models, estimates subtype proportion shifts, and uses a z-score-normalized decomposition to assign each gene a TC_ratio score — the fraction of its DE signal attributable to transcription versus composition. Genes are then classified as transcriptional (real biology), compositional (artifact), or mixed (requires caution). All functions operate natively on SingleCellExperiment objects and return a CDEResult S4 object that extends the standard DE output with full decomposition statistics. |
| Authors: | Subhadip Jana [aut, cre] (ORCID: <https://orcid.org/0009-0003-7860-2853>) |
| Maintainer: | Subhadip Jana <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.99.0 |
| Built: | 2026-06-09 13:46:51 UTC |
| Source: | https://github.com/BiocStaging/scCompoundDE |
scCompoundDE decomposes pseudo-bulk differential expression (DE) signals into two orthogonal components: transcriptional changes (cell-intrinsic expression shifts) and compositional changes (shifts in the relative abundance of cell subtypes within a broad population).
Standard pseudo-bulk DE tools treat a pseudo-bulk sample as if it were homogeneous, confounding true transcriptional change with artifactual signal arising from subtype proportion shifts. For example, if T cells in disease donors are predominantly exhausted (high PDCD1, TOX) while T cells in healthy donors are predominantly naive (high IL7R, CCR7), a standard pseudo-bulk DE analysis will report PDCD1 and IL7R as significantly DE – but these genes changed because the composition of T cells changed, not because T cells themselves changed their transcriptome. scCompoundDE detects and quantifies this confound for every tested gene.
For each gene, scCompoundDE computes a TC_ratio score in
[0, 1]:
TC_ratio ~= 1 – gene is driven by cell-intrinsic transcriptional change (real biology).
TC_ratio ~= 0 – gene is driven by a shift in subtype proportions (compositional artefact).
TC_ratio ~= 0.5 – mixed signal (both components contribute).
compoundDERun the full decomposition pipeline.
Returns a CDEResult S4 object.
filterGenesBySourceExtract transcriptional,
compositional, or mixed gene lists from a CDEResult.
plotDecompositionScatter plot of T_score vs C_score for all genes.
plotProportionStacked bar chart of subtype proportions per condition.
plotTCRatioHistogram of TC_ratio distribution with classification thresholds.
Use scBatchQC first to flag and remove low-quality cells.
Use scFastDE or any pseudo-bulk tool to get DE genes.
Use scCompoundDE to validate whether those DE genes are
transcriptionally driven or compositional artefacts.
Maintainer: Subhadip Jana [email protected] (ORCID)
Authors:
Subhadip Jana [email protected] (ORCID)
Crowell HL et al. (2020). muscat detects subpopulation-specific state transitions from multi-sample multi-condition single-cell transcriptomics data. Nature Communications, 11, 6077.
Then E et al. (2023). Distinguishing cell type composition and cell type-specific effects in bulk tissues. bioRxiv.
Useful links:
Report bugs at https://github.com/SubhadipJana1409/scCompoundDE/issues
Create a new CDEResult object.
CDEResult(deTable, subtypeProportions, subtypeDE, params = list())CDEResult(deTable, subtypeProportions, subtypeDE, params = list())
deTable |
A |
subtypeProportions |
A |
subtypeDE |
A named |
params |
A |
A CDEResult object.
library(S4Vectors) dt <- DataFrame( gene = c("G1", "G2"), logFC = c(1.2, 0.1), AveExpr = c(3.1, 2.0), t = c(4.1, 0.5), P.Value = c(0.001, 0.8), adj.P.Val = c(0.01, 0.9), B = c(2.1, -2.0), T_score = c(1.1, 0.05), C_score = c(0.1, 0.09), T_score_z = c(1.5, 0.2), C_score_z = c(0.2, 0.3), TC_ratio = c(0.88, 0.40), source = c("transcriptional", "mixed") ) pm <- matrix(c(0.6, 0.4, 0.3, 0.7), nrow = 2, dimnames = list(c("D1___ctrl","D1___treat"), c("TypeA","TypeB"))) obj <- CDEResult(deTable = dt, subtypeProportions = pm, subtypeDE = list(), params = list(broad_type = "T_cell")) objlibrary(S4Vectors) dt <- DataFrame( gene = c("G1", "G2"), logFC = c(1.2, 0.1), AveExpr = c(3.1, 2.0), t = c(4.1, 0.5), P.Value = c(0.001, 0.8), adj.P.Val = c(0.01, 0.9), B = c(2.1, -2.0), T_score = c(1.1, 0.05), C_score = c(0.1, 0.09), T_score_z = c(1.5, 0.2), C_score_z = c(0.2, 0.3), TC_ratio = c(0.88, 0.40), source = c("transcriptional", "mixed") ) pm <- matrix(c(0.6, 0.4, 0.3, 0.7), nrow = 2, dimnames = list(c("D1___ctrl","D1___treat"), c("TypeA","TypeB"))) obj <- CDEResult(deTable = dt, subtypeProportions = pm, subtypeDE = list(), params = list(broad_type = "T_cell")) obj
An S4 class storing the output of compoundDE. Every
pseudo-bulk DE gene is assigned a TC_ratio score – the fraction
of its observed fold-change attributable to transcriptional (cell-intrinsic)
versus compositional (subtype proportion shift) signal.
deTableA DataFrame with one row per gene containing
logFC, AveExpr, t, P.Value,
adj.P.Val, B (from the broad limma model),
T_score, C_score, T_score_z, C_score_z,
TC_ratio, and source (transcriptional / compositional /
mixed).
subtypeProportionsA matrix of subtype proportions with
rows = samples (donor___condition) and columns = subtypes.
subtypeDEA named list of per-subtype DataFrames
from the limma DE models.
paramsA list of analysis parameters.
compoundDE decomposes pseudo-bulk differential expression (DE)
signals into two orthogonal components:
Transcriptional (T): Cell-intrinsic expression changes – the gene would be DE even if subtype proportions were held fixed.
Compositional (C): Signal arising from a shift in the relative abundance of subtypes – the gene appears DE only because high-expressing (or low-expressing) subtypes became more or less common.
Standard pseudo-bulk DE tools (DESeq2, edgeR, limma-voom) confound these
two sources. compoundDE fits a separate limma-voom model for each
cell subtype within the broad population, estimates subtype proportion
changes across conditions, and uses a z-score-normalised decomposition to
assign each gene a TC_ratio – the fraction of its DE signal
attributable to transcriptional change.
compoundDE( sce, broad_type, subtype_col, broad_col, donor, condition, contrast = NULL, min_cells = 10L, min_subtypes = 2L, min_cpm = 1, min_donors = 2L, tc_thresh_high = 0.8, tc_thresh_low = 0.2, assay_name = "counts", BPPARAM = SerialParam() )compoundDE( sce, broad_type, subtype_col, broad_col, donor, condition, contrast = NULL, min_cells = 10L, min_subtypes = 2L, min_cpm = 1, min_donors = 2L, tc_thresh_high = 0.8, tc_thresh_low = 0.2, assay_name = "counts", BPPARAM = SerialParam() )
sce |
A |
broad_type |
A |
subtype_col |
A |
broad_col |
A |
donor |
A |
condition |
A |
contrast |
A |
min_cells |
An |
min_subtypes |
An |
min_cpm |
A |
min_donors |
An |
tc_thresh_high |
A |
tc_thresh_low |
A |
assay_name |
A |
BPPARAM |
A |
The decomposition algorithm:
Filter sparse donor-subtype combinations (min_cells).
Compute subtype proportion matrix (donor x
subtype x condition).
For each subtype , aggregate pseudo-bulk and run
limma::voom to obtain per-subtype log-fold-changes
.
Run a broad pseudo-bulk DE (all subtypes collapsed) to obtain the
observed , -values, and FDR.
Compute the transcriptional component:
where is the mean proportion of subtype
across all samples.
Compute the compositional component:
where and is the mean
log2 CPM of gene in subtype .
Z-score normalise both and across genes,
then compute:
Classify each gene as transcriptional
( tc_thresh_high), compositional
( tc_thresh_low), or mixed.
A CDEResult object containing:
deTable: per-gene statistics – logFC,
P.Value, adj.P.Val (from the broad model) plus
T_score, C_score, T_score_z, C_score_z,
TC_ratio, and source.
subtypeProportions: the matrix.
subtypeDE: per-subtype limma results.
params: the analysis parameters.
plotDecomposition, plotProportion,
plotTCRatio, CDEResult
library(SingleCellExperiment) set.seed(42) n_genes <- 150 n_cells <- 120 counts <- matrix(rpois(n_genes * n_cells, 8L), nrow = n_genes, ncol = n_cells) rownames(counts) <- paste0("Gene", seq_len(n_genes)) colnames(counts) <- paste0("Cell", seq_len(n_cells)) # Inject DE signal into first 10 genes for subtype A treatment counts[seq_len(10), 61:90] <- counts[seq_len(10), 61:90] * 4L sce <- SingleCellExperiment(assays = list(counts = counts)) sce$donor <- rep(paste0("D", seq_len(6)), each = 20) sce$cell_type <- "T_cell" sce$subtype <- rep(c("TypeA", "TypeB"), times = 60) sce$condition <- rep(c("ctrl", "treat"), each = 60) result <- compoundDE( sce, broad_type = "T_cell", subtype_col = "subtype", broad_col = "cell_type", donor = "donor", condition = "condition", min_cells = 3L, min_subtypes = 2L, min_donors = 2L ) result head(as.data.frame(deTable(result)))library(SingleCellExperiment) set.seed(42) n_genes <- 150 n_cells <- 120 counts <- matrix(rpois(n_genes * n_cells, 8L), nrow = n_genes, ncol = n_cells) rownames(counts) <- paste0("Gene", seq_len(n_genes)) colnames(counts) <- paste0("Cell", seq_len(n_cells)) # Inject DE signal into first 10 genes for subtype A treatment counts[seq_len(10), 61:90] <- counts[seq_len(10), 61:90] * 4L sce <- SingleCellExperiment(assays = list(counts = counts)) sce$donor <- rep(paste0("D", seq_len(6)), each = 20) sce$cell_type <- "T_cell" sce$subtype <- rep(c("TypeA", "TypeB"), times = 60) sce$condition <- rep(c("ctrl", "treat"), each = 60) result <- compoundDE( sce, broad_type = "T_cell", subtype_col = "subtype", broad_col = "cell_type", donor = "donor", condition = "condition", min_cells = 3L, min_subtypes = 2L, min_donors = 2L ) result head(as.data.frame(deTable(result)))
Returns the per-gene compound DE statistics from a
CDEResult object, including the decomposition scores.
deTable(x, ...) ## S4 method for signature 'CDEResult' deTable(x, ...)deTable(x, ...) ## S4 method for signature 'CDEResult' deTable(x, ...)
x |
A |
... |
Additional arguments (not used). |
A DataFrame with columns logFC, P.Value,
adj.P.Val, T_score, C_score, TC_ratio,
and source.
library(S4Vectors) dt <- DataFrame(gene = "G1", logFC = 1.2, P.Value = 0.001, adj.P.Val = 0.01, AveExpr = 3.1, t = 4.1, B = 2.1, T_score = 1.1, C_score = 0.1, T_score_z = 1.5, C_score_z = 0.2, TC_ratio = 0.88, source = "transcriptional") pm <- matrix(c(0.6, 0.4), nrow = 1, dimnames = list("D1___ctrl", c("TypeA", "TypeB"))) obj <- CDEResult(dt, pm, list(), list(broad_type = "T_cell")) deTable(obj)library(S4Vectors) dt <- DataFrame(gene = "G1", logFC = 1.2, P.Value = 0.001, adj.P.Val = 0.01, AveExpr = 3.1, t = 4.1, B = 2.1, T_score = 1.1, C_score = 0.1, T_score_z = 1.5, C_score_z = 0.2, TC_ratio = 0.88, source = "transcriptional") pm <- matrix(c(0.6, 0.4), nrow = 1, dimnames = list("D1___ctrl", c("TypeA", "TypeB"))) obj <- CDEResult(dt, pm, list(), list(broad_type = "T_cell")) deTable(obj)
A convenience utility to extract subsets of the DE table from a
CDEResult object by source classification
("transcriptional", "compositional", or "mixed")
and optionally by FDR significance.
filterGenesBySource( result, source = "transcriptional", fdr_thresh = 0.05, sort_by = "adj.P.Val" )filterGenesBySource( result, source = "transcriptional", fdr_thresh = 0.05, sort_by = "adj.P.Val" )
result |
A |
source |
A |
fdr_thresh |
A |
sort_by |
A |
A data.frame of filtered DE genes.
library(SingleCellExperiment) set.seed(42) n_genes <- 150 counts <- matrix(rpois(n_genes * 120, 8L), nrow = n_genes, ncol = 120) rownames(counts) <- paste0("Gene", seq_len(n_genes)) colnames(counts) <- paste0("Cell", seq_len(120)) counts[seq_len(10), 61:90] <- counts[seq_len(10), 61:90] * 4L sce <- SingleCellExperiment(assays = list(counts = counts)) sce$donor <- rep(paste0("D", seq_len(6)), each = 20) sce$cell_type <- "T_cell" sce$subtype <- rep(c("TypeA", "TypeB"), times = 60) sce$condition <- rep(c("ctrl", "treat"), each = 60) result <- compoundDE(sce, broad_type = "T_cell", subtype_col = "subtype", broad_col = "cell_type", donor = "donor", condition = "condition", min_cells = 3L, min_subtypes = 2L, min_donors = 2L) # Get only transcriptionally significant genes filterGenesBySource(result, source = "transcriptional") # Get compositional artefacts filterGenesBySource(result, source = "compositional", fdr_thresh = 1)library(SingleCellExperiment) set.seed(42) n_genes <- 150 counts <- matrix(rpois(n_genes * 120, 8L), nrow = n_genes, ncol = 120) rownames(counts) <- paste0("Gene", seq_len(n_genes)) colnames(counts) <- paste0("Cell", seq_len(120)) counts[seq_len(10), 61:90] <- counts[seq_len(10), 61:90] * 4L sce <- SingleCellExperiment(assays = list(counts = counts)) sce$donor <- rep(paste0("D", seq_len(6)), each = 20) sce$cell_type <- "T_cell" sce$subtype <- rep(c("TypeA", "TypeB"), times = 60) sce$condition <- rep(c("ctrl", "treat"), each = 60) result <- compoundDE(sce, broad_type = "T_cell", subtype_col = "subtype", broad_col = "cell_type", donor = "donor", condition = "condition", min_cells = 3L, min_subtypes = 2L, min_donors = 2L) # Get only transcriptionally significant genes filterGenesBySource(result, source = "transcriptional") # Get compositional artefacts filterGenesBySource(result, source = "compositional", fdr_thresh = 1)
Produces a scatter plot of the z-scored transcriptional score
(T_score_z) versus the compositional score (C_score_z)
for every gene, coloured by their source classification. This
visualisation makes it immediately clear which genes are driven by
cell-intrinsic expression changes versus subtype proportion shifts.
plotDecomposition( result, fdr_thresh = 0.05, top_n = 10L, point_size = 1.2, point_alpha = 0.7, colours = c(transcriptional = "#2196F3", compositional = "#F44336", mixed = "#FF9800", ns = "#BDBDBD") )plotDecomposition( result, fdr_thresh = 0.05, top_n = 10L, point_size = 1.2, point_alpha = 0.7, colours = c(transcriptional = "#2196F3", compositional = "#F44336", mixed = "#FF9800", ns = "#BDBDBD") )
result |
A |
fdr_thresh |
A |
top_n |
An |
point_size |
A |
point_alpha |
A |
colours |
A named |
A ggplot2 object.
compoundDE, plotTCRatio,
plotProportion
library(SingleCellExperiment) set.seed(42) n_genes <- 150 counts <- matrix(rpois(n_genes * 120, 8L), nrow = n_genes, ncol = 120) rownames(counts) <- paste0("Gene", seq_len(n_genes)) colnames(counts) <- paste0("Cell", seq_len(120)) counts[seq_len(10), 61:90] <- counts[seq_len(10), 61:90] * 4L sce <- SingleCellExperiment(assays = list(counts = counts)) sce$donor <- rep(paste0("D", seq_len(6)), each = 20) sce$cell_type <- "T_cell" sce$subtype <- rep(c("TypeA", "TypeB"), times = 60) sce$condition <- rep(c("ctrl", "treat"), each = 60) result <- compoundDE(sce, broad_type = "T_cell", subtype_col = "subtype", broad_col = "cell_type", donor = "donor", condition = "condition", min_cells = 3L, min_subtypes = 2L, min_donors = 2L) plotDecomposition(result)library(SingleCellExperiment) set.seed(42) n_genes <- 150 counts <- matrix(rpois(n_genes * 120, 8L), nrow = n_genes, ncol = 120) rownames(counts) <- paste0("Gene", seq_len(n_genes)) colnames(counts) <- paste0("Cell", seq_len(120)) counts[seq_len(10), 61:90] <- counts[seq_len(10), 61:90] * 4L sce <- SingleCellExperiment(assays = list(counts = counts)) sce$donor <- rep(paste0("D", seq_len(6)), each = 20) sce$cell_type <- "T_cell" sce$subtype <- rep(c("TypeA", "TypeB"), times = 60) sce$condition <- rep(c("ctrl", "treat"), each = 60) result <- compoundDE(sce, broad_type = "T_cell", subtype_col = "subtype", broad_col = "cell_type", donor = "donor", condition = "condition", min_cells = 3L, min_subtypes = 2L, min_donors = 2L) plotDecomposition(result)
Produces a stacked bar chart showing the mean proportion of each
subtype within the broad cell type, split by condition. Samples are
shown as individual points overlaid on the bars, making it easy to
see between-donor variability in composition. A significant
compositional shift across conditions is a key driver of
compositional DE genes identified by compoundDE.
plotProportion( result, show_points = TRUE, colours = NULL, point_size = 2, point_alpha = 0.8 )plotProportion( result, show_points = TRUE, colours = NULL, point_size = 2, point_alpha = 0.8 )
result |
A |
show_points |
Logical. If |
colours |
A named or unnamed character vector of colours for
the subtypes. If |
point_size |
A |
point_alpha |
A |
A ggplot2 object.
compoundDE, plotDecomposition,
plotTCRatio
library(SingleCellExperiment) set.seed(42) n_genes <- 150 counts <- matrix(rpois(n_genes * 120, 8L), nrow = n_genes, ncol = 120) rownames(counts) <- paste0("Gene", seq_len(n_genes)) colnames(counts) <- paste0("Cell", seq_len(120)) counts[seq_len(10), 61:90] <- counts[seq_len(10), 61:90] * 4L sce <- SingleCellExperiment(assays = list(counts = counts)) sce$donor <- rep(paste0("D", seq_len(6)), each = 20) sce$cell_type <- "T_cell" sce$subtype <- rep(c("TypeA", "TypeB"), times = 60) sce$condition <- rep(c("ctrl", "treat"), each = 60) result <- compoundDE(sce, broad_type = "T_cell", subtype_col = "subtype", broad_col = "cell_type", donor = "donor", condition = "condition", min_cells = 3L, min_subtypes = 2L, min_donors = 2L) plotProportion(result)library(SingleCellExperiment) set.seed(42) n_genes <- 150 counts <- matrix(rpois(n_genes * 120, 8L), nrow = n_genes, ncol = 120) rownames(counts) <- paste0("Gene", seq_len(n_genes)) colnames(counts) <- paste0("Cell", seq_len(120)) counts[seq_len(10), 61:90] <- counts[seq_len(10), 61:90] * 4L sce <- SingleCellExperiment(assays = list(counts = counts)) sce$donor <- rep(paste0("D", seq_len(6)), each = 20) sce$cell_type <- "T_cell" sce$subtype <- rep(c("TypeA", "TypeB"), times = 60) sce$condition <- rep(c("ctrl", "treat"), each = 60) result <- compoundDE(sce, broad_type = "T_cell", subtype_col = "subtype", broad_col = "cell_type", donor = "donor", condition = "condition", min_cells = 3L, min_subtypes = 2L, min_donors = 2L) plotProportion(result)
Plots the distribution of TC_ratio values across all tested
genes. The TC_ratio measures the fraction of each gene's DE signal
that is attributable to transcriptional (cell-intrinsic) versus
compositional (subtype proportion shift) change. Vertical dashed
lines show the classification thresholds.
plotTCRatio( result, fdr_thresh = 0.05, bins = 40L, colours = c(transcriptional = "#2196F3", compositional = "#F44336", mixed = "#FF9800", ns = "#BDBDBD") )plotTCRatio( result, fdr_thresh = 0.05, bins = 40L, colours = c(transcriptional = "#2196F3", compositional = "#F44336", mixed = "#FF9800", ns = "#BDBDBD") )
result |
A |
fdr_thresh |
A |
bins |
An |
colours |
A named |
A ggplot2 object.
compoundDE, plotDecomposition,
plotProportion
library(SingleCellExperiment) set.seed(42) n_genes <- 150 counts <- matrix(rpois(n_genes * 120, 8L), nrow = n_genes, ncol = 120) rownames(counts) <- paste0("Gene", seq_len(n_genes)) colnames(counts) <- paste0("Cell", seq_len(120)) counts[seq_len(10), 61:90] <- counts[seq_len(10), 61:90] * 4L sce <- SingleCellExperiment(assays = list(counts = counts)) sce$donor <- rep(paste0("D", seq_len(6)), each = 20) sce$cell_type <- "T_cell" sce$subtype <- rep(c("TypeA", "TypeB"), times = 60) sce$condition <- rep(c("ctrl", "treat"), each = 60) result <- compoundDE(sce, broad_type = "T_cell", subtype_col = "subtype", broad_col = "cell_type", donor = "donor", condition = "condition", min_cells = 3L, min_subtypes = 2L, min_donors = 2L) plotTCRatio(result)library(SingleCellExperiment) set.seed(42) n_genes <- 150 counts <- matrix(rpois(n_genes * 120, 8L), nrow = n_genes, ncol = 120) rownames(counts) <- paste0("Gene", seq_len(n_genes)) colnames(counts) <- paste0("Cell", seq_len(120)) counts[seq_len(10), 61:90] <- counts[seq_len(10), 61:90] * 4L sce <- SingleCellExperiment(assays = list(counts = counts)) sce$donor <- rep(paste0("D", seq_len(6)), each = 20) sce$cell_type <- "T_cell" sce$subtype <- rep(c("TypeA", "TypeB"), times = 60) sce$condition <- rep(c("ctrl", "treat"), each = 60) result <- compoundDE(sce, broad_type = "T_cell", subtype_col = "subtype", broad_col = "cell_type", donor = "donor", condition = "condition", min_cells = 3L, min_subtypes = 2L, min_donors = 2L) plotTCRatio(result)
Prints a compact summary of a CDEResult object
including the decomposition breakdown.
## S4 method for signature 'CDEResult' show(object)## S4 method for signature 'CDEResult' show(object)
object |
A |
Invisibly returns object.
Returns the list of per-subtype limma DE DataFrames.
subtypeDE(x, ...) ## S4 method for signature 'CDEResult' subtypeDE(x, ...)subtypeDE(x, ...) ## S4 method for signature 'CDEResult' subtypeDE(x, ...)
x |
A |
... |
Additional arguments (not used). |
A named list of DataFrames, one per subtype.
library(S4Vectors) dt <- DataFrame(gene = "G1", logFC = 1.2, P.Value = 0.001, adj.P.Val = 0.01, AveExpr = 3.1, t = 4.1, B = 2.1, T_score = 1.1, C_score = 0.1, T_score_z = 1.5, C_score_z = 0.2, TC_ratio = 0.88, source = "transcriptional") pm <- matrix(c(0.6, 0.4), nrow = 1, dimnames = list("D1___ctrl", c("TypeA", "TypeB"))) obj <- CDEResult(dt, pm, list(), list(broad_type = "T_cell")) subtypeDE(obj)library(S4Vectors) dt <- DataFrame(gene = "G1", logFC = 1.2, P.Value = 0.001, adj.P.Val = 0.01, AveExpr = 3.1, t = 4.1, B = 2.1, T_score = 1.1, C_score = 0.1, T_score_z = 1.5, C_score_z = 0.2, TC_ratio = 0.88, source = "transcriptional") pm <- matrix(c(0.6, 0.4), nrow = 1, dimnames = list("D1___ctrl", c("TypeA", "TypeB"))) obj <- CDEResult(dt, pm, list(), list(broad_type = "T_cell")) subtypeDE(obj)
Returns the subtype proportion matrix from a
CDEResult object.
subtypeProportions(x, ...) ## S4 method for signature 'CDEResult' subtypeProportions(x, ...)subtypeProportions(x, ...) ## S4 method for signature 'CDEResult' subtypeProportions(x, ...)
x |
A |
... |
Additional arguments (not used). |
A matrix with rows = samples and columns = subtypes.
library(S4Vectors) dt <- DataFrame(gene = "G1", logFC = 1.2, P.Value = 0.001, adj.P.Val = 0.01, AveExpr = 3.1, t = 4.1, B = 2.1, T_score = 1.1, C_score = 0.1, T_score_z = 1.5, C_score_z = 0.2, TC_ratio = 0.88, source = "transcriptional") pm <- matrix(c(0.6, 0.4), nrow = 1, dimnames = list("D1___ctrl", c("TypeA", "TypeB"))) obj <- CDEResult(dt, pm, list(), list(broad_type = "T_cell")) subtypeProportions(obj)library(S4Vectors) dt <- DataFrame(gene = "G1", logFC = 1.2, P.Value = 0.001, adj.P.Val = 0.01, AveExpr = 3.1, t = 4.1, B = 2.1, T_score = 1.1, C_score = 0.1, T_score_z = 1.5, C_score_z = 0.2, TC_ratio = 0.88, source = "transcriptional") pm <- matrix(c(0.6, 0.4), nrow = 1, dimnames = list("D1___ctrl", c("TypeA", "TypeB"))) obj <- CDEResult(dt, pm, list(), list(broad_type = "T_cell")) subtypeProportions(obj)
Returns the per-gene TC_ratio vector – the fraction of DE signal attributable to transcriptional versus compositional change. Values near 1 = transcriptional (real biology); values near 0 = compositional (artifact).
tcRatio(x, ...) ## S4 method for signature 'CDEResult' tcRatio(x, ...)tcRatio(x, ...) ## S4 method for signature 'CDEResult' tcRatio(x, ...)
x |
A |
... |
Additional arguments (not used). |
A named numeric vector of TC_ratio values.
library(S4Vectors) dt <- DataFrame(gene = c("G1","G2"), logFC = c(1.2,0.1), P.Value = c(0.001,0.8), adj.P.Val = c(0.01,0.9), AveExpr = c(3.1,2.0), t = c(4.1,0.5), B = c(2.1,-2.0), T_score = c(1.1,0.05), C_score = c(0.1,0.09), T_score_z = c(1.5,0.2), C_score_z = c(0.2,0.3), TC_ratio = c(0.88,0.40), source = c("transcriptional","mixed")) pm <- matrix(c(0.6,0.4,0.3,0.7), nrow=2, dimnames=list(c("D1___ctrl","D1___treat"),c("TypeA","TypeB"))) obj <- CDEResult(dt, pm, list(), list(broad_type = "T_cell")) tcRatio(obj)library(S4Vectors) dt <- DataFrame(gene = c("G1","G2"), logFC = c(1.2,0.1), P.Value = c(0.001,0.8), adj.P.Val = c(0.01,0.9), AveExpr = c(3.1,2.0), t = c(4.1,0.5), B = c(2.1,-2.0), T_score = c(1.1,0.05), C_score = c(0.1,0.09), T_score_z = c(1.5,0.2), C_score_z = c(0.2,0.3), TC_ratio = c(0.88,0.40), source = c("transcriptional","mixed")) pm <- matrix(c(0.6,0.4,0.3,0.7), nrow=2, dimnames=list(c("D1___ctrl","D1___treat"),c("TypeA","TypeB"))) obj <- CDEResult(dt, pm, list(), list(broad_type = "T_cell")) tcRatio(obj)