The differential_analysis function runs the full
differential analysis workflow in one call, covering three sequential
steps: statistical testing, visualization, and pathway annotation. For
users who prefer fine-grained control over parameters, please refer to
the detailed parameter settings below.
First, count matrices across samples are compared condition-by-condition using a two-round limma-voom framework, identifying genomic regions with significant differences in accessibility. When column clusters are provided, counts within each cluster are aggregated across pairs before testing, and results are reported per cluster. Each pairwise comparison produces a set of significant regions with associated statistics.
Next, the significant regions from each comparison are visualized as log2 count heatmaps, with columns grouped by sample. This allows direct visual inspection of accessibility patterns across conditions.
Finally, the significant regions are submitted to GREAT for pathway enrichment analysis against a user-specified MSigDB gene set collection, revealing the biological processes associated with each set of differential regions. Results are summarised in per-comparison TSV tables and an optional bubble plot.
| Parameter | Type | Default | Description | Example |
|---|---|---|---|---|
cm_path
|
character vector | — |
Paths to per-sample count matrices in .feather format, one
per sample. Must have the same length as conditions. Each
file must contain a pos column and one column per CRF pair.
|
c(“C1.feather”, “C2.feather”, “T1.feather”, “T2.feather”)
|
conditions
|
character vector | — |
Condition labels for each sample in cm_path, in the same
order. Each condition must have at least 2 replicates. All pairwise
comparisons between conditions are tested.
|
c(“C”, “C”, “T”, “T”)
|
sample_names
|
character vector or NULL |
NULL
|
Optional sample names used in output file names and heatmap column
labels. Must be unique and the same length as conditions.
If NULL, names are auto-generated as
<condition><replicate_index>
(e.g. C1, C2, T1).
|
c(“Control_1”, “Control_2”, “Treat_1”, “Treat_2”)
|
out_dir
|
character |
“./”
|
Root output directory for all results. Differential region tables and
heatmaps are written here; pathway enrichment outputs are written to
<out_dir>/pathway_enrichment/. Created recursively if
it does not exist.
|
“./differential”
|
col_cluster_file_path
|
character or NULL |
NULL
|
Path to a TSV file with columns pair and
cluster, mapping CRF pairs to column clusters. When
provided, counts within each cluster are summed across pairs before
testing, and heatmaps expand back to pair-level columns grouped by
sample. When NULL, each pair is tested independently.
|
“bicluster/col_table.tsv”
|
ref_genome
|
character |
“hg38”
|
Reference genome. Controls the TSS source for GREAT and the species for
MSigDB gene set retrieval. Supported: “hg38”,
“mm10”.
|
“mm10”
|
norm_level
|
character |
“crf”
|
Controls the level at which TMM normalization factors are estimated.
“crf” estimates factors independently within each
CRF group, which is appropriate when composition is expected to remain
relatively stable across conditions and only local differences are
anticipated. “global” (recommended for most cases)
estimates a single set of normalization factors across all samples
before any per-group analysis, making it more robust when global
composition shifts substantially between conditions (such as in CRF
knockdown or knockout experiments where the target mark is depleted
genome-wide).
|
norm_level = “global”
|
min_support
|
integer |
2
|
Minimum number of non-zero replicates required within at least one
condition for a genomic region to pass the initial non-zero support
filter before differential testing. Only regions passing this
filter are carried forward to the limma-voom modeling step and
considered for significance testing. For example, with min_support
= 2, a region is retained if it has non-zero counts in at least 2
replicates in Control or at least 2 replicates in Treatment.
|
1
|
lfc_threshold
|
numeric |
0.5
|
Minimum absolute log2 fold-change required for a region to be called
significant after model fitting. A region is considered
significant only if it satisfies both abs(logFC) >
lfc_threshold and adj.P.Val < p_threshold. This
parameter controls the effect size requirement in the final significance
decision.
|
1
|
p_threshold
|
numeric |
0.05
|
P-value threshold for significance. Interpreted according to
p_type.
|
p_threshold = 0.05
|
p_type
|
character |
“fdr”
|
Which p-value to use for filtering: “fdr” (BH-adjusted,
recommended for genome-wide analysis), “nominal” (raw
p-value, suitable for pre-selected gene lists), or
“bonferroni” (conservative correction).
|
p_type = “nominal”
|
apply_annotation
|
logical |
TRUE
|
Whether to perform GREAT-based pathway enrichment annotation on
significant differential regions. Set to FALSE to skip the
pathway annotation step entirely.
|
FALSE
|
plot
|
logical |
TRUE
|
Whether to generate visualizations. Controls both heatmap generation and
the pathway enrichment bubble plot. Set to FALSE to
suppress all plot outputs.
|
FALSE
|
library(multiEpiCore)
# Test Data
cm_root_path <- "count_matrix/"
cm_files <- c("C1_Count_Matrix_800.feather", "C2_Count_Matrix_800.feather", "T1_Count_Matrix_800.feather", "T2_Count_Matrix_800.feather")
cm_path <- file.path(cm_root_path, cm_files)
conditions <- c("C", "C", "T", "T")
sample_names <- c("C1", "C2", "T1", "T2")
out_dir <- "differential"
differential_regions(cm_path = cm_path, conditions = conditions, out_dir = out_dir, norm_level = "crf", min_support = 2, lfc_threshold = 1, p_threshold = 0.05, p_type = "fdr", apply_annotation = TRUE, plot = TRUE)
The differential_regions() function identifies
differential genomic regions between experimental conditions using
limma-voom. An optional column cluster file can be provided to group CRF
pairs into clusters. When provided, differential analysis is performed
at the cluster level (for each cluster, all assigned CRF pairs are
included together). When omitted, each CRF pair is analyzed as its own
group.
Differential analysis is performed using the following workflow:
Normalization
TMM (trimmed mean of M-values) normalization is applied to correct for
composition bias across samples. The level at which normalization
factors are estimated is controlled by norm_level:
"global" (default): A single set of TMM factors is
estimated once across all samples using the full feature space (all
regions × all pairs flattened into a single matrix), before any
per-group analysis. This is recommended for most epigenomic comparisons
and ensures that fold-change estimates are comparable across CRFs."crf": TMM factors are estimated independently within
each CRF group during model fitting. This is more appropriate when
global composition is expected to shift substantially between conditions
— for example, in CRF knockdown or knockout experiments where the target
mark is depleted genome-wide.Non-zero support filtering
Regions are filtered based on signal support across replicates. A region
is retained only if it has non-zero counts in at least
min_support replicates within at least one
condition. This removes regions with insufficient signal for
reliable modeling.
Voom transformation
The filtered count matrix is transformed to log2-CPM values via voom,
which estimates the mean-variance relationship and assigns
observation-level precision weights using the normalization factors
determined in step 1.
Linear modeling and empirical Bayes
moderation
A design matrix is constructed from the input conditions and a linear
model is fitted for each region. Empirical Bayes moderation
(eBayes) is applied to stabilize variance estimates across
regions.
Differential region identification
Regions are defined as differential if they satisfy both:
lfc_thresholdp_threshold (interpreted according to
p_type)| Parameter | Type | Default | Description | Example |
|---|---|---|---|---|
cm_path
|
character vector | — |
Paths to per-sample count matrices in .feather format. Each
file should represent one sample, with rows as genomic regions
(stored in a required pos column) and columns as CRF pairs.
All files are harmonized to the common set of regions and CRF pairs
before analysis.
|
c(“C1.feather”, “C2.feather”, “T1.feather”, “T2.feather”)
|
conditions
|
character vector | — |
Condition labels corresponding to cm_path, in the same
order. Each unique condition must have at least 2 replicates,
because limma-voom is performed on replicated group comparisons.
|
c(“Control”, “Control”, “Treatment”, “Treatment”)
|
sample_names
|
character vector |
NULL
|
Optional unique sample names corresponding to cm_path. If
NULL, names are automatically generated from
conditions in the form of condition + replicate index (for
example, Control1, Control2).
|
c(“C1”, “C2”, “T1”, “T2”)
|
out_dir
|
character |
“./”
|
Output directory for all result files, including full differential tables, significant-region tables, summary tables, summary plots, and significant-region count matrices. |
“diff_results”
|
col_cluster_file_path
|
character |
NULL
|
Optional path to a two-column TSV file with columns pair
and cluster. If provided, the function runs in
cluster-aware mode: CRF pairs assigned to the same cluster are
summed within each sample and tested as one aggregated group. If
NULL, the function runs in per-pair mode, where each
CRF pair is tested independently.
|
“col_cluster.tsv”
|
norm_level
|
character |
“crf”
|
Controls the level at which TMM normalization factors are estimated.
“crf” estimates factors independently within each
CRF group, which is appropriate when composition is expected to remain
relatively stable across conditions and only local differences are
anticipated. “global” (recommended for most cases)
estimates a single set of normalization factors across all samples
before any per-group analysis, making it more robust when global
composition shifts substantially between conditions (such as in CRF
knockdown or knockout experiments where the target mark is depleted
genome-wide).
|
norm_level = “global”
|
min_support
|
integer |
2
|
Minimum number of non-zero replicates required within at least one
condition for a genomic region to pass the initial non-zero support
filter. For example, with min_support = 2, a region is
retained if it has non-zero counts in at least 2 replicates in Control
or at least 2 replicates in Treatment.
|
1
|
lfc_threshold
|
numeric |
0.5
|
Minimum absolute log2 fold-change required for a region to be called
significant after model fitting. A region must satisfy both
abs(logFC) > lfc_threshold and adj.P.Val <
p_threshold.
|
1
|
p_threshold
|
numeric |
0.05
|
P-value threshold for significance. Interpreted according to
p_type.
|
p_threshold = 0.05
|
p_type
|
character |
“fdr”
|
Which p-value to use for filtering: “fdr” (BH-adjusted,
recommended for genome-wide analysis), “nominal” (raw
p-value, suitable for pre-selected gene lists), or
“bonferroni” (conservative correction).
|
p_type = “nominal”
|
The function automatically derives all pairwise comparisons from the
unique values in conditions (sorted alphabetically, in the
form <test>_vs_<ref>), and creates one
subdirectory per comparison under out_dir. All output files
are written into the corresponding subdirectory:
<comparison>/<cluster|pair>_all.tsv
pos field in the count matrix.| pos | logFC | AveExpr | t | P.Value | adj.P.Val | B |
|---|---|---|---|---|---|---|
| <chr> | <dbl> | <dbl> | <dbl> | <dbl> | <dbl> | <dbl> |
| chr9_130356001_130356800 | 4.0866 | 0.2914 | 11.5638 | 1.14e-07 | 0.0331 | 7.7404 |
| chr10_101139201_101140000 | 3.8606 | 0.2378 | 10.9880 | 1.95e-07 | 0.0331 | 7.2410 |
| chr10_100614401_100615200 | 3.9058 | 0.4437 | 10.7582 | 2.44e-07 | 0.0331 | 7.0467 |
| chr5_148827201_148828000 | 3.8131 | 0.1777 | 10.6754 | 2.64e-07 | 0.0331 | 6.9650 |
| chr15_77552001_77552800 | 4.0206 | 0.3255 | 10.5539 | 2.98e-07 | 0.0331 | 6.9716 |
| … | ||||||
This table shows differential analysis results for H3K4me1 in the test dataset.
<comparison>/<cluster|pair>_sig.tsv
<comparison>/<cluster|pair>_sig_raw_counts.tsv
_sig.tsv when at least one
significant region is detected.| pos | C1 | C2 | T1 | T2 |
|---|---|---|---|---|
| chr9_130356001_130356800 | 0 | 0 | 16.4753 | 7.4848 |
| chr10_101139201_101140000 | 0.0215 | 0 | 11.5733 | 8.7793 |
| chr10_100614401_100615200 | 0.1848 | 0 | 14.2299 | 9.7483 |
| chr5_148827201_148828000 | 0 | 0 | 11.4695 | 7.7631 |
| chr15_77552001_77552800 | 0 | 0 | 9.7289 | 14.0664 |
| … | ||||
This table shows differential analysis results for H3K4me1 in the test dataset.
<comparison>/<cluster|pair>_sig_log2_cpm.tsv
_sig.tsv when at least one
significant region is detected.| pos | C1 | C2 | T1 | T2 |
|---|---|---|---|---|
| chr9_130356001_130356800 | -1.7753 | -1.6832 | 2.5930 | 2.0310 |
| chr10_101139201_101140000 | -1.7147 | -1.6832 | 2.1014 | 2.2478 |
| chr10_100614401_100615200 | -1.3215 | -1.6832 | 2.3883 | 2.3911 |
| chr5_148827201_148828000 | -1.7753 | -1.6832 | 2.0889 | 2.0805 |
| chr15_77552001_77552800 | -1.7753 | -1.6832 | 1.8622 | 2.8984 |
| … | ||||
This table shows differential analysis results for H3K4me1 in the test dataset.
<comparison>/summary.tsv Includes:
| group | n_rows_before | n_rows_after_nonzero | n_rows_after_mean | n_sig | n_up | n_down |
|---|---|---|---|---|---|---|
| H3K27ac | 3860350 | 45078 | 45078 | 0 | 0 | 0 |
| H3K27me3 | 3860350 | 1297331 | 1297331 | 15829 | 8727 | 7102 |
| H3K4me1 | 3860350 | 908557 | 908557 | 194 | 189 | 5 |
| H3K4me3 | 3860350 | 528144 | 528144 | 7423 | 5067 | 2356 |
| H3K9me2 | 3860350 | 166729 | 166729 | 0 | 0 | 0 |
| H3K9me3 | 3860350 | 1075802 | 1075802 | 15311 | 8505 | 6806 |
<comparison>/summary.pdf
library(multiEpiCore)
# Test data
cm_root_path <- "count_matrix/"
cm_files <- c("C1_Count_Matrix_800.feather", "C2_Count_Matrix_800.feather", "T1_Count_Matrix_800.feather", "T2_Count_Matrix_800.feather")
cm_path <- file.path(cm_root_path, cm_files)
conditions <- c("C", "C", "T", "T")
sample_names <- c("C1", "C2", "T1", "T2")
out_dir <- "differential"
differential_regions(cm_path = cm_path, conditions = conditions, out_dir = out_dir, norm_level = "crf", min_support = 2, lfc_threshold = 1, p_threshold = 0.05, p_type = "fdr")
The differential_heatmap() function generates
per-comparison, per-group heatmaps for all significant differential
regions produced by differential_regions(). It iterates
over the full result object returned by
differential_regions() and dispatches each comparison-group
combination to differential_heatmap_single(), which renders
a region × sample log2-CPM heatmap as a PDF file.
Log2-CPM values are read directly from the
_sig_log2_cpm.tsv output of
differential_regions(), which are derived from voom
transformation using globally estimated TMM normalization factors. No
additional transformation is applied.
When the underlying analysis used column clustering
(col_cluster_file_path), columns in the heatmap represent
individual sample:pair combinations within the cluster,
grouped and titled by sample. Without clustering, each column represents
one sample directly.
| Parameter | Type | Default | Description | Example |
|---|---|---|---|---|
dr_result
|
nested list | — |
The return value of differential_regions(). A two-level
nested list structured as dr_result[[grp_name]][[cmp_tag]],
where the first level keys are cluster or pair names
(e.g. “cluster4”, “H3K27ac_peak1”) and the
second level keys are comparison tags (e.g. “T_vs_C”). Each
leaf is the file path to the corresponding _sig_counts.tsv.
|
dr_result <- differential_regions(…)
|
out_dir
|
character |
“./”
|
Output directory for heatmap PDFs. Created recursively if it does not
exist. One PDF is written per comparison-group combination, named
<cmp_tag>_<grp_name>.pdf.
|
“heatmaps”
|
show_colnames
|
logical |
FALSE
|
Whether to display individual column names on the heatmap. When
FALSE, only the sample-level column group titles are shown.
Set to TRUE to additionally show individual pair
identifiers within each sample group.
|
TRUE
|
col_width_mm
|
numeric |
40
|
Width per individual pair column in mm. Total heatmap width is computed
as n_pairs × col_width_mm + (n_samples − 1) × 8 mm, where
the second term accounts for the fixed 8 mm gap between sample groups.
In cluster mode (when col_cluster_file_path was supplied to
differential_regions()), each sample group contains
multiple pair columns; col_width_mm still refers to a
single pair column, so wider clusters automatically occupy
proportionally more space. In non-cluster mode each sample has exactly
one column, so col_width_mm equals the per-sample width
directly.
|
30
|
row_height_mm
|
numeric |
0.5
|
Height per region row in mm. Total heatmap body height is
n_sig_regions × row_height_mm mm, so the PDF scales
automatically with the number of significant regions. Note that values
below ~0.35 mm (one pixel at 72 dpi) will be visually indistinguishable;
for large region counts (>1000) a value of 0.13–0.5 mm produces dense
stripe patterns comparable to a fixed-height layout.
|
1.0
|
random_seed
|
integer |
42
|
Random seed passed to set.seed() before each raster
rendering call to ensure pixel-level reproducibility across runs.
|
123
|
Output is organized by comparison tag (cmp_tag) read
from dr_result:
<comparison>/<cluster|pair>.pdf
This figure shows differential analysis heatmap for cluster 4 in the test dataset.
library(multiEpiCore)
# Test data
dr_result <- list(
H3K4me1 = list(
T_vs_C = "differential/T_vs_C/H3K4me1_sig_log2_cpm.tsv"
),
H3K27me3 = list(
T_vs_C = "differential/T_vs_C/H3K27me3_sig_log2_cpm.tsv"
),
H3K4me3 = list(
T_vs_C = "differential/T_vs_C/H3K4me3_sig_log2_cpm.tsv"
),
H3K9me3 = list(
T_vs_C = "differential/T_vs_C/H3K9me3_sig_log2_cpm.tsv"
)
)
differential_heatmap(
dr_result = dr_result,
out_dir = "differential"
)
The differential_pathway_annotation() function performs
pathway enrichment analysis on the significant differential regions from
each comparison-group combination using GREAT (Genomic
Regions Enrichment of Annotations Tool). GREAT assigns genomic regions
to nearby genes via basal-plus-extension TSS domains, then tests for
over-representation of gene sets using a binomial test. Gene sets are
sourced from MSigDB via the
msigdbr package, and can be configured to use any available
collection such as Hallmark, Reactome, or GO terms.
Each comparison-group combination (e.g. T vs C within cluster 4) is tested independently. Results are written as per-comparison TSV tables and optionally visualised as a bubble plot that summarises enrichment patterns across all comparisons at a glance.
| Parameter | Type | Default | Description | Example |
|---|---|---|---|---|
dr_result
|
nested list | — |
The return value of differential_regions(). A two-level
nested list structured as dr_result[[grp_name]][[cmp_tag]],
where each leaf is the file path to the corresponding
_sig_counts.tsv. Each comparison-group combination becomes
one GREAT query set.
|
dr_result <- differential_regions(…)
|
out_dir
|
character |
“./”
|
Output directory for enrichment TSV tables and the bubble plot PDF.
Created recursively if it does not exist. One TSV is written per query
set, named
pathway_annotation_<cmp_tag>_<grp_name>.tsv.
|
“pathway”
|
ref_genome
|
character |
“hg38”
|
Reference genome. Controls both the TSS source used by GREAT
(“hg38” → TxDb.Hsapiens.UCSC.hg38.knownGene,
“mm10” → TxDb.Mmusculus.UCSC.mm10.knownGene)
and the species passed to msigdbr(). Must be one of
“hg38” or “mm10”.
|
“mm10”
|
msigdb_collection
|
character |
“H”
|
MSigDB collection abbreviation. Common values: “H”
(Hallmark, 50 curated biological states), “C2” (curated
gene sets including KEGG and Reactome), “C5” (GO gene
sets). See msigdbr::msigdbr_collections() for the full
list.
|
“C2”
|
msigdb_subcollection
|
character or NULL |
NULL
|
MSigDB sub-collection abbreviation. Required when
msigdb_collection has subcollections. For example,
“CP:REACTOME” or “CP:KEGG_LEGACY” under
“C2”, and “GO:BP”, “GO:MF”, or “GO:CC” under “C5”. Leave
NULL for collections without subcollections such as
“H”.
|
“CP:REACTOME”
|
plot
|
logical |
TRUE
|
Whether to generate a bubble plot PDF
(pathway_annotation.pdf) summarising enrichment across all
query sets. Each row is a pathway ordered by best adjusted p-value
across query sets; bubble size encodes log2(1 +
fold_enrichment) and color encodes −log10(padj).
|
FALSE
|
Output is organized by comparison tag (cmp_tag) read
from dr_result, with a pathway_annotation/
subdirectory created under each:
<cmp_tag>/pathway_annotation/pathway_annotation_<grp_name>.tsvpathway : Pathway or gene set name, with
collection-specific prefixes removed (e.g. HALLMARK_
stripped for collection "H")hits_region: Number of input regions associated with at
least one gene in the gene setfold: Fold enrichment of observed over expected region
hitsp: Binomial test p-valuepadj: BH-adjusted p-value across all tested gene
setshits_gene: Number of genes in the gene set that were
hit by at least one input region| pathway | hits_region | fold | p | padj | hits_gene |
|---|---|---|---|---|---|
| <chr> | <int> | <dbl> | <dbl> | <dbl> | <int> |
| ESTROGEN_RESPONSE_LATE | 264 | 1.7437 | 0 | 0 | 103 |
| ESTROGEN_RESPONSE_EARLY | 309 | 1.6681 | 0 | 0 | 112 |
| HEME_METABOLISM | 210 | 1.7305 | 1.20e-13 | 2.00e-12 | 112 |
| P53_PATHWAY | 214 | 1.6654 | 2.28e-12 | 2.85e-11 | 99 |
| ADIPOGENESIS | 180 | 1.4767 | 4.18e-07 | 4.18e-06 | 88 |
| APICAL_JUNCTION | 202 | 1.4176 | 1.24e-06 | 1.04e-05 | 94 |
| UV_RESPONSE_UP | 160 | 1.4729 | 2.03e-06 | 1.41e-05 | 72 |
| TNFA_SIGNALING_VIA_NFKB | 255 | 1.3487 | 2.25e-06 | 1.41e-05 | 109 |
| XENOBIOTIC_METABOLISM | 153 | 1.4038 | 3.55e-05 | 1.97e-04 | 77 |
| KRAS_SIGNALING_DN | 207 | 1.2889 | 2.19e-04 | 1.09e-03 | 82 |
| MYOGENESIS | 189 | 1.2961 | 3.06e-04 | 1.39e-03 | 94 |
| APICAL_SURFACE | 68 | 1.5145 | 7.63e-04 | 3.18e-03 | 22 |
| IL6_JAK_STAT3_SIGNALING | 71 | 1.4481 | 1.82e-03 | 7.00e-03 | 38 |
| COMPLEMENT | 182 | 1.2447 | 2.18e-03 | 7.80e-03 | 85 |
| APOPTOSIS | 153 | 1.2603 | 2.98e-03 | 9.94e-03 | 78 |
| UNFOLDED_PROTEIN_RESPONSE | 86 | 1.3636 | 3.37e-03 | 1.01e-02 | 46 |
| COAGULATION | 106 | 1.3185 | 3.44e-03 | 1.01e-02 | 55 |
| HYPOXIA | 208 | 1.2078 | 4.09e-03 | 1.13e-02 | 99 |
| PEROXISOME | 83 | 1.3033 | 1.12e-02 | 2.95e-02 | 43 |
| DNA_REPAIR | 80 | 1.3021 | 1.28e-02 | 3.20e-02 | 55 |
| ALLOGRAFT_REJECTION | 148 | 1.1887 | 2.11e-02 | 4.99e-02 | 68 |
| IL2_STAT5_SIGNALING | 203 | 1.1559 | 2.20e-02 | 4.99e-02 | 103 |
| NOTCH_SIGNALING | 41 | 1.3528 | 3.66e-02 | 7.95e-02 | 22 |
| MYC_TARGETS_V2 | 34 | 1.3812 | 4.17e-02 | 8.70e-02 | 19 |
| HEDGEHOG_SIGNALING | 70 | 1.2359 | 4.68e-02 | 9.24e-02 | 23 |
| INTERFERON_GAMMA_RESPONSE | 153 | 1.1489 | 4.80e-02 | 9.24e-02 | 82 |
| … | truncated | ||||
This table shows pathway annotation result for cluster 4 in the test dataset.
<cmp_tag>/pathway_annotation/pathway_annotation.pdf
(when plot = TRUE)
This figure shows pathway annotation result for cluster 4 in the test dataset.
library(multiEpiCore)
# Test data
dr_result <- list(
H3K4me1 = list(
T_vs_C = "differential/T_vs_C/H3K4me1_sig_log2_cpm.tsv"
),
H3K27me3 = list(
T_vs_C = "differential/T_vs_C/H3K27me3_sig_log2_cpm.tsv"
),
H3K4me3 = list(
T_vs_C = "differential/T_vs_C/H3K4me3_sig_log2_cpm.tsv"
),
H3K9me3 = list(
T_vs_C = "differential/T_vs_C/H3K9me3_sig_log2_cpm.tsv"
)
)
differential_pathway_annotation(
dr_result = dr_result,
out_dir = "differential/pathway_annotation"
)