| name | bio-de-deseq2-basics |
| description | Perform differential expression analysis using DESeq2 in R/Bioconductor. Use for analyzing RNA-seq count data, creating DESeqDataSet objects, running the DESeq workflow, and extracting results with log fold change shrinkage. Use when performing DE analysis with DESeq2. |
| tool_type | r |
| primary_tool | DESeq2 |
DESeq2 Basics
Differential expression analysis using DESeq2 for RNA-seq count data.
Required Libraries
library(DESeq2)
library(apeglm)
Installation
if (!require('BiocManager', quietly = TRUE))
install.packages('BiocManager')
BiocManager::install('DESeq2')
BiocManager::install('apeglm')
Creating DESeqDataSet
From Count Matrix
dds <- DESeqDataSetFromMatrix(countData = counts,
colData = coldata,
design = ~ condition)
From SummarizedExperiment
library(SummarizedExperiment)
dds <- DESeqDataSet(se, design = ~ condition)
From tximport (Salmon/Kallisto)
library(tximport)
txi <- tximport(files, type = 'salmon', tx2gene = tx2gene)
dds <- DESeqDataSetFromTximport(txi, colData = coldata, design = ~ condition)
Standard DESeq2 Workflow
dds <- DESeqDataSetFromMatrix(countData = counts,
colData = coldata,
design = ~ condition)
keep <- rowSums(counts(dds)) >= 10
dds <- dds[keep,]
dds$condition <- relevel(dds$condition, ref = 'control')
dds <- DESeq(dds)
res <- results(dds)
resLFC <- lfcShrink(dds, coef = 'condition_treated_vs_control', type = 'apeglm')
Design Formulas
design = ~ condition
design = ~ batch + condition
design = ~ genotype + treatment + genotype:treatment
design = ~ genotype + treatment
Specifying Contrasts
resultsNames(dds)
res <- results(dds, name = 'condition_treated_vs_control')
res <- results(dds, contrast = c('condition', 'treated', 'control'))
res <- results(dds, contrast = list('conditionB', 'conditionA'))
Log Fold Change Shrinkage
resLFC <- lfcShrink(dds, coef = 'condition_treated_vs_control', type = 'apeglm')
resLFC <- lfcShrink(dds, coef = 'condition_treated_vs_control', type = 'ashr')
resLFC <- lfcShrink(dds, coef = 'condition_treated_vs_control', type = 'normal')
Setting Significance Thresholds
res <- results(dds)
res <- results(dds, alpha = 0.05)
res <- results(dds, lfcThreshold = 1)
Accessing DESeq2 Results
summary(res)
sig <- subset(res, padj < 0.05)
resOrdered <- res[order(res$padj),]
resOrdered <- res[order(abs(res$log2FoldChange), decreasing = TRUE),]
res_df <- as.data.frame(res)
Result Columns
| Column | Description |
|---|
baseMean | Mean of normalized counts across all samples |
log2FoldChange | Log2 fold change (treatment vs control) |
lfcSE | Standard error of log2 fold change |
stat | Wald statistic |
pvalue | Raw p-value |
padj | Adjusted p-value (Benjamini-Hochberg) |
Normalization and Counts
normalized_counts <- counts(dds, normalized = TRUE)
sizeFactors(dds)
vsd <- vst(dds, blind = FALSE)
rld <- rlog(dds, blind = FALSE)
Multi-Factor Designs
dds <- DESeqDataSetFromMatrix(countData = counts,
colData = coldata,
design = ~ batch + condition)
dds <- DESeq(dds)
res <- results(dds, name = 'condition_treated_vs_control')
Interaction Models
dds <- DESeqDataSetFromMatrix(countData = counts,
colData = coldata,
design = ~ genotype + treatment + genotype:treatment)
dds <- DESeq(dds)
res_interaction <- results(dds, name = 'genotypeKO.treatmentdrug')
res_interaction <- results(dds, contrast = list(
c('genotypeKO.treatmentdrug'),
c()
))
Likelihood Ratio Test
dds <- DESeq(dds, test = 'LRT', reduced = ~ batch)
res <- results(dds)
Pre-Filtering Strategies
keep <- rowSums(counts(dds)) >= 10
dds <- dds[keep,]
keep <- rowSums(counts(dds) >= 10) >= 3
dds <- dds[keep,]
keep <- rowMeans(counts(dds, normalized = TRUE)) >= 10
dds <- dds[keep,]
Working with Existing Objects
design(dds) <- ~ batch + condition
dds <- DESeq(dds)
dds_subset <- dds[, dds$group == 'A']
dds_genes <- dds[rownames(dds) %in% gene_list,]
Exporting Results
write.csv(as.data.frame(resOrdered), file = 'deseq2_results.csv')
write.csv(as.data.frame(normalized_counts), file = 'normalized_counts.csv')
Common Errors
| Error | Cause | Solution |
|---|
| "design matrix not full rank" | Confounded variables or missing levels | Check coldata for confounding |
| "counts matrix should be integers" | Non-integer counts (e.g., from tximport) | Use DESeqDataSetFromTximport() |
| "all samples have 0 counts" | Gene filtering issue | Check count matrix format |
| "factor levels not in colData" | Typo in design formula | Verify column names in coldata |
Deprecated Features
| Feature | Status | Alternative |
|---|
| No-replicate designs | Removed (v1.22) | Require biological replicates |
betaPrior = TRUE | Deprecated | Use lfcShrink() instead |
rlog() for large datasets | Not recommended | Use vst() for >100 samples |
Quick Reference: Workflow Steps
dds <- DESeqDataSetFromMatrix(counts, coldata, design = ~ condition)
keep <- rowSums(counts(dds)) >= 10
dds <- dds[keep,]
dds$condition <- relevel(dds$condition, ref = 'control')
dds <- DESeq(dds)
res <- lfcShrink(dds, coef = resultsNames(dds)[2], type = 'apeglm')
sig_genes <- subset(res, padj < 0.05 & abslog2FoldChange
Related Skills
- edger-basics - Alternative DE analysis with edgeR
- de-visualization - MA plots, volcano plots, heatmaps
- de-results - Extract and export significant genes