9 FCS-GSEA analysis

9.1 Introduction to FCS methods

The ORA method is easy to use, but it may lose useful information when the differences between genes are small. For example, a gene may play an essential role in a pathway but still be filtered out by the fold-change cutoff if its expression change is small.

Unlike ORA, FCS tools do not use a fixed threshold to select differentially expressed genes. Instead, they assign a differential expression score to each detected gene and then evaluate whether the scores in each gene set are more positive or negative than expected by chance.

According to the article “Ten Years of Pathway Analysis: Current Approaches and Outstanding Challenges”:

FCS approaches include GSEA, GlobalTest, sigPathway, SAFE, GSA, PADOG, PCOT2, FunCluster, SAM-GS, and Category, among others.

Next, we will walk through the popular Gene Set Enrichment Analysis (GSEA) method, which uses permutation-based testing to determine whether a gene set is significantly associated with higher or lower scores.

9.2 Introduction to GSEA

To perform GSEA, you need an ordered, pre-ranked gene list, such as genes ranked by decreasing logFC values.

GSEA generally includes three steps:

  1. Calculate the enrichment score (ES). The ES indicates how strongly the genes in a gene set are overrepresented at either the top or the bottom of the ranked list. GSEA starts at the top of the list and calculates a running sum. The score increases when a gene belongs to the target gene set and decreases when it does not.

  2. Estimate the statistical significance of the ES. This is done with a permutation test, which generates a null distribution for the ES.

  3. Adjust for multiple testing when many gene sets are analyzed at the same time. The enrichment score of each gene set is normalized, and a false discovery rate is calculated.

GSEA overview

Figure 9.1: GSEA overview

For a more detailed explanation of the GSEA procedure, please visit https://www.pathwaycommons.org/guide/primers/data_analysis/gsea or https://github.com/crazyhottommy/RNA-seq-analysis/blob/master/GSEA_explained.md.

9.3 Basic usage

The main arguments are:

  • genelist: a pre-ranked gene list in decreasing order (a named numeric vector), such as a list ranked by logFC or correlation. Entrez IDs, Ensembl IDs, and gene symbols are accepted.
  • geneset: a two-column data frame containing term IDs and gene IDs. We recommend using geneset to prepare gene sets.
  • p_cutoff: a numeric cutoff for both the p-value and adjusted p-value. The default is 0.05.
  • q_cutoff: a numeric cutoff for the q-value. The default is 0.05.

9.3.1 Step 1: Prepare a pre-ranked gene list

data(geneList, package = "genekitr")
head(geneList)
##       948      1638    158471     10610      6947 100133941 
##  5.780170  5.633027  4.683610  3.875120  3.357670  3.322533

9.3.2 Step 2: Prepare a gene set

gs <- geneset::getGO(org = "human",ont = "mf")

9.3.3 Step 3: Run GSEA

gse <- genGSEA(genelist = geneList, geneset = gs)

Now, let’s take a look at the result.

The returned object is a list that mainly contains the analysis results (gsea_df), the input gene list (genelist), and the input gene set (geneset).

class(gse)
## [1] "list"
names(gse)
## [1] "gsea_df"  "genelist" "geneset"  "exponent" "org"
head(gse$genelist)
##                    ID    logfc
## CD36             CD36 5.780170
## DCT               DCT 5.633027
## PRUNE2         PRUNE2 4.683610
## ST6GALNAC2 ST6GALNAC2 3.875120
## TCN1             TCN1 3.357670
## CD24             CD24 3.322533
head(gse$geneset)
##           id  gene
## 1 GO:0000009  PIGV
## 2 GO:0000009 ALG12
## 3 GO:0000009  ALG2
## 4 GO:0000014 ERCC1
## 5 GO:0000014 ERCC4
## 6 GO:0000014 MRE11
head(gse$gsea_df, 5)
##              Hs_MF_ID                            Description setSize
## GO:0003678 GO:0003678                  DNA helicase activity      57
## GO:0017116 GO:0017116  single-stranded DNA helicase activity      24
## GO:0008094 GO:0008094  ATP-dependent activity, acting on DNA     118
## GO:0017056 GO:0017056 structural constituent of nuclear pore      21
## GO:0003697 GO:0003697            single-stranded DNA binding     111
##            enrichmentScore       NES       pvalue     p.adjust       qvalue
## GO:0003678      -0.7407188 -2.517871 1.938079e-11 3.422094e-09 2.141764e-09
## GO:0017116      -0.8723960 -2.505996 3.696204e-10 4.153189e-08 2.599329e-08
## GO:0008094      -0.6440061 -2.481783 7.319114e-14 2.261606e-11 1.415457e-11
## GO:0017056      -0.8612352 -2.417513 1.422998e-08 1.465688e-06 9.173208e-07
## GO:0003697      -0.6286387 -2.370217 6.659685e-12 1.371895e-09 8.586191e-10
##            rank                   leading_edge
## GO:0003678 1163  tags=46%, list=6%, signal=43%
## GO:0017116 1123  tags=71%, list=6%, signal=67%
## GO:0008094 1172  tags=32%, list=6%, signal=30%
## GO:0017056 1567  tags=67%, list=8%, signal=61%
## GO:0003697 2061 tags=35%, list=11%, signal=31%
##                                                                                                                                                                                                                        core_enriched_geneID
## GO:0003678                                                                                   RUVBL2/DHX9/CHTF18/FANCM/G3BP1/TWNK/RUVBL1/RFC5/RFC2/DNA2/RFC4/ZGRF1/MCM3/MCM8/BRIP1/MCM2/MCM7/RFC3/POLQ/DSCC1/MCM5/MCM4/MCM6/ERCC6L/BLM/RAD51
## GO:0017116                                                                                                                                         DHX9/CHTF18/RFC5/RFC2/DNA2/RFC4/MCM3/MCM8/MCM2/MCM7/RFC3/POLQ/DSCC1/MCM5/MCM4/MCM6/RAD51
## GO:0008094              CHD1/RUVBL2/DHX9/CHTF18/RAD51C/FANCM/XRCC3/G3BP1/TWNK/RUVBL1/MSH6/DMC1/TOP2A/RFC5/MSH2/TTF2/RFC2/DNA2/RFC4/ZGRF1/MCM3/MCM8/BRIP1/MCM2/MCM7/RFC3/POLQ/DSCC1/MCM5/MCM4/ATAD5/MCM6/HELLS/RAD54L/ERCC6L/BLM/RAD51/XRCC2
## GO:0017056                                                                                                                                         NUP98/NUP54/NUP93/NUP153/NUP88/NUP160/NUP188/NUP155/NUP85/NDC1/NUP58/NUP35/NUP107/NUP205
## GO:0003697 HNRNPU/RPA1/POLR2H/TDP1/NOL12/MLH1/HMGB1/RAD23A/FAM111A/HSPD1/DHX9/TOP1/TOP3A/SMC4/TWNK/SMC2/HMGB2/RNF138/POLA1/DMC1/MSH2/RPA2/RAD18/MCM3/MCM8/MCM2/MCM7/NEIL3/MCM5/MCM4/MCM6/MMS22L/RAD54L/BRCA2/RAD51AP1/BLM/RAD51/CDC45/MCM10
##              log2err core_enriched_count
## GO:0003678 0.8634154                  26
## GO:0017116 0.8140358                  17
## GO:0008094 0.9545416                  38
## GO:0017056 0.7477397                  14
## GO:0003697 0.8870750                  39
##                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     all_enriched_geneID
## GO:0003678                                                                                                                                                                                                                                                                                                                                                                                          MCM3/RECQL5/DHX30/ERCC2/MCM5/TWNK/WRNIP1/RUVBL1/BLM/MCM7/HFM1/MCM9/RECQL4/MCM2/ASCC3/RECQL/CHTF18/FBH1/BRIP1/WRN/MCMDC2/MCM6/MCM8/IGHMBP2/RUVBL2/ATRX/DDX3X/DHX9/DNA2/ERCC3/XRCC6/MCM4/MRE11/RAD51/UPF1/RFC2/RFC3/RFC4/RFC5/SUPV3L1/XRCC5/CHD1L/RAD50/G3BP1/POLQ/SETX/ERCC6L/CHTF8/ZGRF1/CHD8/FANCM/DSCC1/PIF1/NAV2/HELB/HELQ/DHX36
## GO:0017116                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             MCM3/MCM5/WRNIP1/MCM7/MCM9/MCM2/CHTF18/MCMDC2/MCM6/MCM8/DHX9/DNA2/MCM4/RAD51/RFC2/RFC3/RFC4/RFC5/POLQ/CHTF8/DSCC1/PIF1/HELB/HELQ
## GO:0008094 MCM3/RECQL5/DHX30/ERCC2/RAD51B/MCM5/CHD2/SMARCA4/TWNK/CHD4/WRNIP1/RUVBL1/BLM/MCM7/CHD3/HFM1/MCM9/RECQL4/MCM2/ASCC3/RECQL/CHTF18/FBH1/TTF2/BRIP1/CHD7/HLTF/SMARCA2/CHD6/RFC3/WRN/CHD8/MCMDC2/RFC5/SMARCA5/RFC2/CHD5/CHD1/RAD51/RFC4/SMARCA1/MCM6/MCM8/IGHMBP2/SMARCAD1/RAD17/RUVBL2/ATRX/CDK7/CHRNA4/DAXX/DDX1/DDX3X/DHX9/DNA2/ERCC3/BPTF/XRCC6/MSH6/HELLS/MCM4/MLH1/MRE11/MSH2/MSH3/MYD88/PMS1/PMS2P1/PMS2P3/PMS2/RAD51C/RBBP4/UPF1/RFC1/SMARCB1/SMARCC1/SMARCC2/SMARCD1/SMARCD3/SMARCE1/SUPV3L1/TOP2A/TOP2B/TP53/XRCC2/XRCC3/XRCC5/ARID1A/RAD54L/BTAF1/CHD1L/RAD50/G3BP1/POLQ/DMC1/MORC2/WAPL/SETX/RAD54L2/SPO11/MLH3/CECR2/SMARCAL1/RSF1/INO80/ERCC6L/CHTF8/ZGRF1/FANCM/DSCC1/ATAD5/PIF1/ZRANB3/NAV2/HELB/HELQ/DHX36/ARID2
## GO:0017056                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      NUP58/NUP155/NUP107/POM121L2/NUP160/NUP85/NPAP1/TPR/NUP188/NUP214/NUP133/NUP153/NUP54/NUP35/NUP93/NUP88/NUP98/NUTF2/NUP205/NUP62CL/NDC1
## GO:0003697                                          APTX/ERCC1/MCM3/BIVM/SSBP1/MEIOB/RAD51B/SETMAR/MCM5/ERCC4/RAD51AP1/TDP1/TWNK/SMC6/CDC45/MCM7/POLA1/MCM9/MCM2/TERF1/RPA2/SMC5/RNF138/RPA1/RPA3/MCMDC2/RAD50/MCM10/XPC/NUCKS1/PCBP1/POT1/RAD51/RPA4/MCM6/MCM8/CTC1/BLM/BRCA2/CRY2/DHX9/HMGB1/HMGB2/HNRNPA1/HNRNPA2B1/HNRNPU/HSPD1/IGHMBP2/JCHAIN/MAPT/MCM4/MLH1/MSH2/MSH3/YBX1/PMS2/POLR2G/POLR2H/POU4F1/PURA/PURB/RAD23A/RAD23B/RBMS1/RECQL/SMARCA1/HLTF/TERF2/TOP1/TOP3A/TP53/TSN/RAD54L/FUBP1/FUBP3/LONP1/RECQL4/HNRNPDL/SMC4/LRPPRC/SMC2/POLR3C/SUB1/DMC1/RTF1/SSBP2/SSBP3/SAMHD1/SMARCAL1/TDP2/WBP11/PCBP3/TERF2IP/RADX/NEIL3/RAD18/HMCES/REXO4/WDR48/FAM111A/NABP1/NABP2/NOL12/STN1/SPRTN/ZRANB3/FBH1/SWSAP1/SSBP4/DHX36/MMS22L
##            all_enriched_count
## GO:0003678                 57
## GO:0017116                 24
## GO:0008094                118
## GO:0017056                 21
## GO:0003697                111

About the gsea_df result

  • Description: the name of the gene set.

  • setSize: the number of genes in the gene set that have gene-level statistic values in the input list. For example, a pathway gene set may contain 58 genes, such as HALLMARK_MYC_TARGETS_V2, but only 54 of them may be present in the input gene list. In this case, the result will show setSize = 54.

  • enrichmentScore: also called ES, as in the Broad GSEA implementation. It reflects the degree to which a gene set is overrepresented at the top or bottom of a ranked gene list.

  • NES: the normalized enrichment score and the primary statistic used to examine gene set enrichment results. By normalizing the enrichment score, GSEA accounts for differences in gene set size and correlations between gene sets and the expression dataset. Therefore, NES values can be used to compare results across gene sets. A positive NES indicates that the genes in set S are mainly found near the top of the ranked list, which usually corresponds to genes with logFC > 0 or upregulated genes.

  • rank: the position in the ranked list where the maximum enrichment score occurs. If a gene set reaches its maximum enrichment score near the top or bottom of the ranked list, the rank at the maximum will be either very small or very large.

  • leading_edge: contains three statistics:

    • tags: the percentage of gene hits that appear before the peak for a positive ES or after the peak for a negative ES. It indicates the proportion of genes that contribute to the enrichment score.
    • list: the percentage of genes in the ranked list that appear before the peak for a positive ES or after the peak for a negative ES. It gives an idea of where the enrichment score is reached in the list.
    • signal: the strength of the enrichment signal. If the entire gene set appears within the first N positions of the list, the signal is strongest and may reach 100%. If the genes are spread throughout the list, the signal decreases toward 0%.
  • core_enriched_geneID and core_enriched_count: the leading-edge genes (the subset of the gene set that contributes most to the enrichment score, i.e. genes before the peak for a positive ES or after the peak for a negative ES) and their number.

  • all_enriched_geneID and all_enriched_count: all genes of the gene set that are present in the ranked list, and their number.

  • geneID_symbol: gene IDs are kept in the same ID type as the gene set (e.g. Entrez for KEGG and MSigDB, symbol for GO). For Entrez-based gene sets, this extra column gives the corresponding gene symbols.

  • log2err: the expected error of the log2(p-value) estimate, reported by the underlying fgsea algorithm.

9.4 Advanced usage

9.4.1 Additional arguments

padj_method, min_gset_size and max_gset_size work the same as in the ORA section. Two more things are specific to GSEA:

  • set_seed: GSEA estimates p-values by permutation, so results can differ slightly between runs. Set set_seed = TRUE to get the same result every time for the same input.
  • Duplicated genes: if several input IDs are mapped to the same gene after ID conversion (e.g. an alias and the official symbol of the same gene), only the first (highest ranked) one is kept, and a message tells you how many were removed.

9.4.2 Simplify GO GSEA results

The GO result of genGSEA uses the same ID column name as genORA (e.g. Hs_MF_ID), so it can be passed to simGO() directly (see the ORA section for details):

sim_gse <- simGO(gse$gsea_df, sim_method = "Resnik")
dim(gse$gsea_df); dim(sim_gse)
## [1] 88 15
## [1] 34 15

9.5 Export GSEA results

genekitr provides an easy way to export analysis results for further editing and sharing.

Multiple data frames are saved as separate sheets in a single Excel file, and the column names are automatically formatted in bold.

genekitr::expoSheet(data_list = gse,
                    data_name = names(gse),
                    filename = "gsea_result.xlsx",
                    dir = "./")
Export results

Figure 9.2: Export results