A DESeq2 teaching workflow for pairwise treatment comparisons, with data import, gene filtering, VST visualization, differential-expression testing, and plotting.


Teaching document: DESeq2_pairwise_demo-20231212
Output: HTML document
Author: CTLin, ICOB Data directory

/home/workshop/demo/02_DE/

Rmd

~/Shared/518_projects/workshop_20231213/DESeq2_pairwise_demo.Rmd

DESeq2 pairwise comparison

Library

library(DESeq2)
library(readr)
library(tibble)
library(pheatmap)
library(dplyr)
library(ggplot2)
source("/home/workshop/demo/02_DE/Hmap_PatternCluster_func.R")
source("/home/workshop/demo/02_DE/prepare_df_for_certainGene_pattern_func.R")

# run mkdir DESeq2_output/R_output in the terminal

Import data

# import the tab-delimited text file of count matrix
count_matrix <- read_delim("~/count_matrix.txt",
                           delim = "\t",
                           escape_double = FALSE,
                           trim_ws = TRUE)

count_matrix <- column_to_rownames(count_matrix, "Geneid")

# import the metadata
metadata <- read_delim("/home/workshop/demo/02_DE/metadata_pairwise.txt",
                       delim = "\t",
                       escape_double = FALSE,
                       trim_ws = TRUE)


metadata$rep <- factor(metadata$rep, levels = c("r1","r2","r3"))
metadata$treatment <- factor(metadata$treatment, levels = c("ctrl","drug"))
# eliminate rows with NA
table(is.na(count_matrix))
# no NA

# check if there are duplicated gene id?
length(unique(rownames(count_matrix)))
# no

# the read count cut-off of the low-expression genes
low_exp_read_count = 10
# minimum samples that express this gene (總共有24個 sample)
minimum_exp_sample = 3

dds object & gene filtering

dds_pw <- DESeqDataSetFromMatrix(countData= count_matrix,
                                colData= metadata,
                                design= ~treatment+rep) # batch effect

keep <- rowSums(counts(dds_pw)>low_exp_read_count) >= minimum_exp_sample
dds_pw <- dds_pw[keep, ] # 17539 genes

VST transformation

# Output cross-sample normalization counts
# Size factor
dds_pw<-estimateSizeFactors(dds_pw)

normalized_counts <- counts(dds_pw, normalized=TRUE)
normalized_counts <- tibble::rownames_to_column(as.data.frame(normalized_counts), "Gene_id")

write.csv(normalized_counts, file = "DESeq2_output/R_output/DESeq2_cross-sample_normalized_counts.csv")





# vst transformation
vst <- vst(dds_pw, blind=FALSE)
plotPCA(vst,intgroup="treatment")
plotPCA(vst,intgroup="rep")
vst_mat <- assay(vst)

write.csv(vst_mat, file = "DESeq2_output/R_output/DESeq2_cross-sample_normalized_vst-counts.csv")
dds_wald <- DESeq(dds_pw,
              test = "Wald",
              fitType = "parametric",
              betaPrior = F) #  whether or not to put a zero-mean normal prior on the non-intercept coefficients
plotDispEsts(dds_wald)

DEG between treatments

result_drug_ctrl <-results(dds_wald,
                      contrast=c("treatment","drug","ctrl"),      # base factor level 放後面
                      alpha = 0.05,
                      independentFiltering = TRUE,
                      pAdjustMethod = "fdr")
# before shrinkage
result_drug_ctrl

# afger shrinkage
result_drug_ctrl_shrink_ashr <- lfcShrink(dds_wald,
                                      type="ashr",
                                      res = result_drug_ctrl)

plotMA(result_drug_ctrl)
plotMA(result_drug_ctrl_shrink_ashr)

subset DEG

result_drug_ctrl_shrink_ashr_df <- as.data.frame(result_drug_ctrl_shrink_ashr)
result_drug_ctrl_shrink_ashr_df <- result_drug_ctrl_shrink_ashr_df[order(result_drug_ctrl_shrink_ashr_df$padj),]


deg_drug_ctrl_padj01 <- subset(result_drug_ctrl_shrink_ashr_df,
                                 (result_drug_ctrl_shrink_ashr_df$padj < 0.05 &
                                  abs(result_drug_ctrl_shrink_ashr_df$log2FoldChange) > 1))




deg_drug_ctrl_padj01 <- tibble::rownames_to_column(deg_drug_ctrl_padj01, "Gene_id")
# -> 166 DEGs

write.csv(deg_drug_ctrl_padj01, file = "DESeq2_output/R_output/DEGs_drug_ctrl_padj<0.01.csv")

Visualization

result_drug_ctrl_shrink_ashr_df <- na.omit(result_drug_ctrl_shrink_ashr_df)
write.csv(result_drug_ctrl_shrink_ashr_df, file = "DESeq2_output/R_output/DESeq2_drug_ctrl_Shrinklog2FC.csv")





# plot
result_drug_ctrl_shrink_ashr_df <- as.data.frame(result_drug_ctrl_shrink_ashr)
result_drug_ctrl_shrink_ashr_df$shape <- ifelse(result_drug_ctrl_shrink_ashr_df$padj<10^-30,2,20)
result_drug_ctrl_shrink_ashr_df$padj[result_drug_ctrl_shrink_ashr_df$padj<10^-30] <- 10^-30
pdf(file = "DESeq2_output/R_output/volcano_drug.vs.ctrl.pdf", height = 5, width = 7)
with(result_drug_ctrl_shrink_ashr_df,
     plot(log2FoldChange,
          -log10(padj),
          pch=shape,
          main=""))

# Add colored points: blue if log2FC < -1 and padj < 0.05
# red if log2FC > 1 and padj<0.05)
with(subset(result_drug_ctrl_shrink_ashr_df,
            padj<.05 & log2FoldChange < -1),
     points(log2FoldChange,
            -log10(padj),
            pch=shape,
            col="blue"))

with(subset(result_drug_ctrl_shrink_ashr_df,
            padj<.05 & log2FoldChange > 1),
     points(log2FoldChange,
            -log10(padj),
            pch=shape,
            col="red"))

legend("topright",
       legend=c("log2FC < -1 and padj < 0.05",
                "log2FC > 1 and padj < 0.05"),
       col=c("blue", "red"),
       cex = 0.6,
       pch = 20)
dev.off()
← Back to projects