Contents

0.1 Introduction

This vignette analyzes GSE63409, an Illumina 450K methylation dataset from acute myeloid leukemia (AML). The dataset contains 15 AML patients represented by leukemia stem and blast cell samples, and normal hematopoietic stem and progenitor cell controls from healthy bone marrow.

The original study, Hu et al. 2019 (doi:10.21037/atm.2019.11.122), used GSE63409 together with an expression dataset to identify AML-relevant methylation/expression signals, immune and differentiation pathways, and candidate prognostic genes.

0.2 Setup and Dependencies

try(devtools::load_all(), silent = TRUE)
suppressPackageStartupMessages({
    try(library(CMEnt), silent = TRUE)
    library(minfi)
    library(data.table)
    library(ggplot2)
    library(dplyr)
    library(GenomicRanges)
})

getBenchmarkFile <- function(filename) {
    benchmark_file <- ""
    folder <- "microarray450k"
    if (getwd() == "notebooks") {
        benchmark_file <- file.path("cached_results", folder, filename)
    } else if ("NAMESPACE" %in% dir()) {
        benchmark_file <- file.path("notebooks", "cached_results", folder, filename)
    } else {
        benchmark_file <- file.path("cached_results", folder, filename)
    }
    dir.create(dirname(benchmark_file), showWarnings = FALSE, recursive = TRUE)
    benchmark_file
}

split_ids <- function(x) {
    ids <- unlist(strsplit(stats::na.omit(as.character(x)), ","), use.names = FALSE)
    unique(ids[nzchar(ids)])
}

has_text <- function(x) {
    !is.na(x) & nzchar(as.character(x))
}

short_label <- function(x, width = 65L) {
    ifelse(nchar(x) > width, paste0(substr(x, 1L, width - 3L), "..."), x)
}

0.2.1 Install External Dependencies

r <- getOption("repos")
if (is.null(r) || is.na(r["CRAN"]) || r["CRAN"] %in% c("@CRAN@", "")) {
  options(repos = c(CRAN = "https://cloud.r-project.org"))
}
if (!requireNamespace("BiocManager", quietly = TRUE)) {
    install.packages("BiocManager")
}

if (!requireNamespace("tidyr", quietly = TRUE)) {
    install.packages("tidyr")
}

if (!requireNamespace("scales", quietly = TRUE)) {
    install.packages("scales")
}

if (!requireNamespace("IlluminaHumanMethylation450kanno.ilmn12.hg19", quietly = TRUE)) {
    BiocManager::install("IlluminaHumanMethylation450kanno.ilmn12.hg19", update = FALSE, ask = FALSE)
}

if (!requireNamespace("TxDb.Hsapiens.UCSC.hg19.knownGene", quietly = TRUE)) {
    BiocManager::install("TxDb.Hsapiens.UCSC.hg19.knownGene", update = FALSE, ask = FALSE)
}

if (!requireNamespace("org.Hs.eg.db", quietly = TRUE)) {
    BiocManager::install("org.Hs.eg.db", update = FALSE, ask = FALSE)
}

if (!requireNamespace("missMethyl", quietly = TRUE)) {
    BiocManager::install("missMethyl", update = FALSE, ask = FALSE)
}

0.3 Load Data

Covariates are: - predictedSex: the sex predicted from methylation data, which can be a strong confounder in methylation analyses. - subject.id.ch1: the patient ID - source_name_ch1: the cell type

covariates <- c("predictedSex", "subject.id.ch1", "source_name_ch1")
sample_group_col <- "subject.status.ch1"

beta <- getBenchmarkFile("GSE63409_beta_values.tsv.gz")
samplesheet <- getBenchmarkFile("GSE63409_samplesheet.tsv")

zenodo_base_url <- "https://zenodo.org/records/20592944/files/"
if (!file.exists(beta)) {
    curl::curl_download(
        url = paste0(zenodo_base_url, basename(beta), "?download=1"),
        destfile = beta
    )
}
if (!file.exists(samplesheet)) {
    curl::curl_download(
        url = paste0(zenodo_base_url, basename(samplesheet), "?download=1"),
        destfile = samplesheet
    )
}


pheno <- fread(samplesheet)
pheno[[sample_group_col]] <- factor(pheno[[sample_group_col]], levels = c("normal", "AML"))
pheno <- as.data.frame(pheno)
rownames(pheno) <- pheno$V1
array_type <- "450K"
genome <- "hg19"

beta_handler <- CMEnt::getBetaHandler(beta, array = array_type, genome = genome)
beta_mat <- as.matrix(beta_handler$getBeta())
locs <- beta_handler$getBetaLocs()
logit2 <- function(x) log2(x) - log2(1 - x)
mvalues <- logit2(beta_mat)
pheno$casecontrol <- pheno[[sample_group_col]] == "AML"

0.4 Find Differentially Methylated Positions

dmps_file <- getBenchmarkFile("dmps.rds")
if (!file.exists(dmps_file)) {
    dmps <- CMEnt::findDMPsArray(
        beta_handler,
        pheno,
        sample_group_col = sample_group_col,
        id_col = "V1",
        covariates = covariates,
        array = array_type,
        genome = genome,
        njobs = max(1L, min(8L, parallel::detectCores(logical = TRUE) - 1L))
    )
    # sort DMPs by location
    rownames(dmps) <- dmps$site_id
    dmps <- dmps[rownames(locs), , drop = FALSE]
    dmps <- dmps[!is.na(dmps$pval), ]
    dmps$qval <- p.adjust(dmps$pval, method = "BH")

    case_idx <- which(pheno$casecontrol)
    ctrl_idx <- which(!pheno$casecontrol)
    dmps$delta_beta <- rowMeans(beta_mat[rownames(dmps), case_idx, drop = FALSE]) -
        rowMeans(beta_mat[rownames(dmps), ctrl_idx, drop = FALSE])

    dmps_gr <- makeGRangesFromDataFrame(
        data.frame(
            chr = locs$chr,
            start = locs$start,
            end = locs$end,
            pval = dmps$pval,
            qval = dmps$qval,
            stat = dmps$qval,
            delta_beta = dmps$delta_beta
        ),
        keep.extra.columns = TRUE
    )
    names(dmps_gr) <- rownames(dmps)
    saveRDS(dmps_gr, dmps_file)
} else {
    dmps_gr <- readRDS(dmps_file)
}
dmps <- as.data.frame(dmps_gr)
sig_dmps <- dmps[dmps$qval < 0.05 & abs(dmps$delta_beta) >= 0.05, ]
cat(sprintf("Found %d significant DMPs (FDR < 0.05, |delta beta| >= 0.05)\n", nrow(sig_dmps)))

Found 72556 significant DMPs (FDR < 0.05, |delta beta| >= 0.05)

0.5 Method 1: CMEnt

cment_file <- getBenchmarkFile("dmrs.CMEnt.rds")
if (!file.exists(cment_file)) {
    cment_njobs <- max(1L, min(8L, parallel::detectCores(logical = TRUE) - 1L))
    options("CMEnt.verbose" = 1)
    options("CMEnt.njobs" = cment_njobs)
    cat(sprintf("CMEnt parallel jobs: %d\n", cment_njobs))
    cat(sprintf("parallel::detectCores(): %d\n", parallel::detectCores(logical = TRUE)))
    cat("Starting CMEnt::buildDMRs()...\n")
    flush.console()
    start_time <- Sys.time()
    dmrs_cment <- CMEnt::buildDMRs(
        beta = beta_handler,
        seeds = sig_dmps,
        pheno = pheno,
        sample_group_col = sample_group_col,
        casecontrol_col = "casecontrol",
        covariates = covariates,
        max_bridge_seeds_gaps  = 1,
        max_bridge_extension_gaps = 3,
        min_seeds = 2,
        min_sites = 3,
        ext_site_delta_beta = 0.2,
        max_lookup_dist = 1000,
        max_pval = 0.05,
        entanglement = "weak",
        njobs = cment_njobs,
        verbose = 1
    )
    end_time <- Sys.time()
    time_cment <- end_time - start_time
    saveRDS(list(dmrs = dmrs_cment, time = time_cment), cment_file)
} else {
    ret <- readRDS(cment_file)
    dmrs_cment <- ret$dmrs
    time_cment <- ret$time
}

cat(sprintf("CMEnt: Found %d DMRs in %d seconds\n", length(dmrs_cment), round(as.numeric(time_cment, units = "secs"))))

CMEnt: Found 8654 DMRs in 1049 seconds

0.6 CMEnt Region Summary

if (!all(c("in_promoter_of", "in_gene_body_of", "delta_beta_promoter", "delta_beta_gene_body") %in% colnames(mcols(dmrs_cment))) &&
    requireNamespace("TxDb.Hsapiens.UCSC.hg19.knownGene", quietly = TRUE) &&
    requireNamespace("org.Hs.eg.db", quietly = TRUE)) {
    dmrs_cment <- CMEnt::annotateDMRsWithGenes(dmrs_cment, genome = genome)
}
for (gene_col in c("in_promoter_of", "in_gene_body_of")) {
    if (!gene_col %in% colnames(mcols(dmrs_cment))) {
        mcols(dmrs_cment)[[gene_col]] <- NA_character_
    }
}
for (delta_col in c("delta_beta_promoter", "delta_beta_gene_body")) {
    if (!delta_col %in% colnames(mcols(dmrs_cment))) {
        mcols(dmrs_cment)[[delta_col]] <- NA_real_
    }
}

dmr_delta_col <- if ("sites_delta_beta" %in% colnames(mcols(dmrs_cment))) {
    "sites_delta_beta"
} else {
    "delta_beta"
}
dmr_delta <- as.numeric(mcols(dmrs_cment)[[dmr_delta_col]])
dmr_direction <- ifelse(dmr_delta > 0, "Hypermethylated in AML", "Hypomethylated in AML")
dmr_summary <- data.frame(
    DMRs = length(dmrs_cment),
    Median_width_bp = median(width(dmrs_cment)),
    Mean_width_bp = round(mean(width(dmrs_cment)), 1),
    Total_coverage_bp = sum(width(dmrs_cment)),
    Median_delta_beta = round(median(dmr_delta, na.rm = TRUE), 4),
    Mean_abs_delta_beta = round(mean(abs(dmr_delta), na.rm = TRUE), 4),
    Hypermethylated_DMRs = sum(dmr_delta > 0, na.rm = TRUE),
    Hypomethylated_DMRs = sum(dmr_delta < 0, na.rm = TRUE)
)

knitr::kable(dmr_summary, caption = "CMEnt DMR summary for AML versus normal samples")

Table 1: CMEnt DMR summary for AML versus normal samples
DMRs Median_width_bp Mean_width_bp Total_coverage_bp Median_delta_beta Mean_abs_delta_beta Hypermethylated_DMRs Hypomethylated_DMRs
8654 1315 1740.2 15059673 0.0082 0.1087 5034 3620
dmrs_cment_only_promoter_or_gene_body <- dmrs_cment[!(is.finite(mcols(dmrs_cment)$delta_beta_promoter) & is.finite(mcols(dmrs_cment)$delta_beta_gene_body))]
dmr_effect_df <- bind_rows(
    data.frame(
        Region = "Promoter-overlapping DMRs",
        Width = width(dmrs_cment_only_promoter_or_gene_body),
        Delta_beta = as.numeric(mcols(dmrs_cment_only_promoter_or_gene_body)$delta_beta_promoter)
    ),
    data.frame(
        Region = "Gene-body-overlapping DMRs",
        Width = width(dmrs_cment_only_promoter_or_gene_body),
        Delta_beta = as.numeric(mcols(dmrs_cment_only_promoter_or_gene_body)$delta_beta_gene_body)
    )
) |>
    filter(is.finite(Delta_beta)) |>
    mutate(Direction = factor(
        ifelse(Delta_beta > 0, "Hypermethylated in AML", "Hypomethylated in AML"),
        levels = c("Hypermethylated in AML", "Hypomethylated in AML")
    ))

library(dplyr)
library(ggplot2)
library(scales)

ignore_abs_delta <- !is.finite(dmr_effect_df$Delta_beta) | abs(dmr_effect_df$Delta_beta) < 0.05
dmr_effect_df <- dmr_effect_df[!ignore_abs_delta,]
# Summary per Region and Direction
dmr_summary <- dmr_effect_df %>%
  group_by(Region, Direction) %>%
  summarise(
    median_delta_beta = median(Delta_beta, na.rm = TRUE),
    n_dmrs = n(),
    .groups = "drop"
  )

# Define two y-levels for the two summary bars
y_max <- max(dmr_effect_df$Width, na.rm = TRUE)

dmr_summary <- dmr_summary %>%
  mutate(
    bar_y = case_when(
      Direction == "Hypermethylated in AML" ~ y_max * 2.0,
      Direction == "Hypomethylated in AML"  ~ y_max * 3.2
    ),
    label_y = bar_y * 1.12
  )

# Expand y-range so the bars and labels fit
y_upper <- max(dmr_summary$label_y) * 1.15

ggplot(dmr_effect_df, aes(x = Delta_beta, y = Width, color = Direction)) +
  geom_hline(
    yintercept = median(dmr_effect_df$Width, na.rm = TRUE),
    linewidth = 0.2,
    color = "grey70"
  ) +
  geom_vline(xintercept = 0, linewidth = 0.2, color = "grey70") +
  geom_point(alpha = 0.55, size = 1.2) +

  # Separate horizontal bars for hypo and hyper
  geom_segment(
    data = dmr_summary,
    aes(
      x = 0,
      xend = median_delta_beta,
      y = bar_y,
      yend = bar_y,
      color = Direction
    ),
    inherit.aes = FALSE,
    linewidth = 5,
    lineend = "butt"
  ) +

  # Labels for each bar
  geom_text(
    data = dmr_summary,
    aes(
      x = median_delta_beta,
      y = label_y,
      label = paste0(
        "median Δβ = ", round(median_delta_beta, 3),
        "\nDMRs = ", n_dmrs
      )
    ),
    inherit.aes = FALSE,
    color = "black",
    size = 3,
    hjust = ifelse(dmr_summary$median_delta_beta >= 0, -0.05, 1.05)
  ) +

  facet_wrap(~Region, nrow = 1) +
  scale_y_log10(
    limits = c(min(dmr_effect_df$Width[dmr_effect_df$Width > 0], na.rm = TRUE), y_upper),
    labels = comma
  ) +
  scale_color_manual(
    values = c(
      "Hypermethylated in AML" = "#B8405E",
      "Hypomethylated in AML" = "#247BA0"
    )
  ) +
  coord_cartesian(clip = "off") +
  theme_minimal() +
  labs(
    title = "CMEnt DMR Effect Size and Width by Gene Context",
    x = "Context-specific delta beta (AML - normal)",
    y = "DMR width (bp, log scale)",
    color = ""
  )

0.7 CpG and Gene Context

gene_context_df <- data.frame(
    Context = c("Promoter", "Gene body", "Promoter and gene body", "No annotated gene overlap"),
    DMRs = c(
        sum(has_text(mcols(dmrs_cment)$in_promoter_of)),
        sum(has_text(mcols(dmrs_cment)$in_gene_body_of)),
        sum(has_text(mcols(dmrs_cment)$in_promoter_of) & has_text(mcols(dmrs_cment)$in_gene_body_of)),
        sum(!has_text(mcols(dmrs_cment)$in_promoter_of) & !has_text(mcols(dmrs_cment)$in_gene_body_of))
    )
) |>
    mutate(Percentage = round(100 * DMRs / length(dmrs_cment), 1))

knitr::kable(gene_context_df, caption = "Gene context of CMEnt DMRs")

Table 2: Gene context of CMEnt DMRs
Context DMRs Percentage
Promoter 5701 65.9
Gene body 7379 85.3
Promoter and gene body 5560 64.2
No annotated gene overlap 1134 13.1
ggplot(gene_context_df, aes(x = reorder(Context, DMRs), y = DMRs, fill = Context)) +
    geom_col(width = 0.7) +
    coord_flip() +
    scale_y_continuous(labels = scales::comma) +
    theme_minimal() +
    theme(legend.position = "none") +
    labs(title = "CMEnt DMR Gene Context", x = "", y = "DMRs")

if (requireNamespace("IlluminaHumanMethylation450kanno.ilmn12.hg19", quietly = TRUE)) {
    library(IlluminaHumanMethylation450kanno.ilmn12.hg19)
    anno <- as.data.frame(minfi::getAnnotation(IlluminaHumanMethylation450kanno.ilmn12.hg19))
    anno$probe_id <- rownames(anno)

    dmr_site_ids <- split_ids(mcols(dmrs_cment)$sites)
    dmr_site_context <- anno[intersect(dmr_site_ids, rownames(anno)), c("probe_id", "Relation_to_Island")]
    dmp_site_context <- anno[intersect(rownames(sig_dmps), rownames(anno)), c("probe_id", "Relation_to_Island")]

    site_context_df <- bind_rows(
        dmp_site_context |> mutate(Source = "Significant DMPs"),
        dmr_site_context |> mutate(Source = "Sites inside CMEnt DMRs")
    ) |>
        count(Source, Relation_to_Island, name = "Sites") |>
        group_by(Source) |>
        mutate(Percentage = round(100 * Sites / sum(Sites), 1)) |>
        ungroup()

    knitr::kable(site_context_df, caption = "CpG island context of significant DMPs and sites inside CMEnt DMRs")
}

Table 3: CpG island context of significant DMPs and sites inside CMEnt DMRs
Source Relation_to_Island Sites Percentage
Significant DMPs Island 15527 21.4
Significant DMPs N_Shelf 3821 5.3
Significant DMPs N_Shore 12188 16.8
Significant DMPs OpenSea 28474 39.2
Significant DMPs S_Shelf 3289 4.5
Significant DMPs S_Shore 9257 12.8
Sites inside CMEnt DMRs Island 34457 44.3
Sites inside CMEnt DMRs N_Shelf 2049 2.6
Sites inside CMEnt DMRs N_Shore 15149 19.5
Sites inside CMEnt DMRs OpenSea 13572 17.5
Sites inside CMEnt DMRs S_Shelf 1403 1.8
Sites inside CMEnt DMRs S_Shore 11136 14.3
if (exists("site_context_df")) {
    context_levels <- site_context_df |>
        group_by(Relation_to_Island) |>
        summarise(Max_sites = max(Sites), .groups = "drop") |>
        arrange(Max_sites) |>
        pull(Relation_to_Island)
    plot_context_df <- site_context_df |>
        mutate(
            Relation_to_Island = factor(Relation_to_Island, levels = context_levels),
            Source = factor(Source, levels = c("Significant DMPs", "Sites inside CMEnt DMRs"))
        )
    diff_df <- plot_context_df |>
        dplyr::select(Source, Relation_to_Island, Sites) |>
        tidyr::pivot_wider(names_from = Source, values_from = Sites, values_fill = 0) |>
        dplyr::mutate(
            Difference = `Sites inside CMEnt DMRs` - `Significant DMPs`,
            Label = paste0("Delta=", scales::comma(Difference)),
            Label_x = pmax(`Significant DMPs`, `Sites inside CMEnt DMRs`)
        )

    ggplot(plot_context_df, aes(x = Sites, y = Relation_to_Island, fill = Source)) +
        geom_col(data = dplyr::filter(plot_context_df, Source == "Significant DMPs"), width = 0.78, alpha = 0.45) +
        geom_col(data = dplyr::filter(plot_context_df, Source == "Sites inside CMEnt DMRs"), width = 0.48, alpha = 0.9) +
        geom_text(data = diff_df, aes(x = Label_x, y = Relation_to_Island, label = Label), inherit.aes = FALSE, hjust = -0.05, size = 3) +
        scale_x_continuous(labels = scales::comma, expand = expansion(mult = c(0, 0.2))) +
        scale_fill_manual(values = c("Significant DMPs" = "grey65", "Sites inside CMEnt DMRs" = "#0072B2")) +
        theme_minimal() +
        labs(title = "CpG Island Context", x = "Sites", y = "", fill = "")
}

0.8 AML Pathway and Marker Gene Scan

The table below is a targeted DMR scan of AML genetics, signaling, and hematopoietic/myeloid marker genes.

gene_pattern <- function(gene) {
    paste0("(^|,)", gene, "($|,)")
}

dmr_gene_summary <- function(gene) {
    promoter_hits <- grepl(gene_pattern(gene), as.character(mcols(dmrs_cment)$in_promoter_of))
    body_hits <- grepl(gene_pattern(gene), as.character(mcols(dmrs_cment)$in_gene_body_of))
    dmr_hits <- promoter_hits | body_hits
    data.frame(
        Gene = gene,
        CMEnt_DMRs = sum(dmr_hits),
        Promoter_DMRs = sum(promoter_hits),
        Gene_body_DMRs = sum(body_hits),
        Mean_DMR_delta_beta = round(mean(dmr_delta[dmr_hits], na.rm = TRUE), 4)
    )
}

aml_prior_genes <- data.frame(
    Gene = c(
        "NPM1", "FLT3", "KIT", "RUNX1", "TP53", "TET2", "DNMT3A", "CXCR4", "NAT10",
        "JAK2", "STAT3", "STAT5A", "STAT5B", "HOXA9", "HOXA10",
        "CD34", "ITGAM", "SPI1", "CEBPA", "GATA2"
    ),
    Theme = c(
        rep("AML genetics/prognosis", 9),
        rep("JAK-STAT/HOXA signaling", 6),
        rep("Hematopoietic and myeloid differentiation", 5)
    )
)

prior_dmr_summary <- bind_rows(lapply(aml_prior_genes$Gene, dmr_gene_summary))

prior_gene_table <- aml_prior_genes |>
    left_join(prior_dmr_summary, by = "Gene") |>
    mutate(
        CMEnt_DMRs = tidyr::replace_na(CMEnt_DMRs, 0L),
        Methylation_signal = CMEnt_DMRs > 0
    ) |>
    arrange(desc(Methylation_signal), desc(CMEnt_DMRs), Gene)

knitr::kable(prior_gene_table, digits = 4, caption = "Targeted AML gene scan using CMEnt DMRs")

Table 4: Targeted AML gene scan using CMEnt DMRs
Gene Theme CMEnt_DMRs Promoter_DMRs Gene_body_DMRs Mean_DMR_delta_beta Methylation_signal
HOXA9 JAK-STAT/HOXA signaling 2 1 2 -0.0007 TRUE
CD34 Hematopoietic and myeloid differentiation 1 1 1 0.0699 TRUE
GATA2 Hematopoietic and myeloid differentiation 1 1 1 0.0149 TRUE
HOXA10 JAK-STAT/HOXA signaling 1 1 1 0.0706 TRUE
RUNX1 AML genetics/prognosis 1 1 1 -0.2875 TRUE
STAT3 JAK-STAT/HOXA signaling 1 0 1 -0.4134 TRUE
CEBPA Hematopoietic and myeloid differentiation 0 0 0 NaN FALSE
CXCR4 AML genetics/prognosis 0 0 0 NaN FALSE
DNMT3A AML genetics/prognosis 0 0 0 NaN FALSE
FLT3 AML genetics/prognosis 0 0 0 NaN FALSE
ITGAM Hematopoietic and myeloid differentiation 0 0 0 NaN FALSE
JAK2 JAK-STAT/HOXA signaling 0 0 0 NaN FALSE
KIT AML genetics/prognosis 0 0 0 NaN FALSE
NAT10 AML genetics/prognosis 0 0 0 NaN FALSE
NPM1 AML genetics/prognosis 0 0 0 NaN FALSE
SPI1 Hematopoietic and myeloid differentiation 0 0 0 NaN FALSE
STAT5A JAK-STAT/HOXA signaling 0 0 0 NaN FALSE
STAT5B JAK-STAT/HOXA signaling 0 0 0 NaN FALSE
TET2 AML genetics/prognosis 0 0 0 NaN FALSE
TP53 AML genetics/prognosis 0 0 0 NaN FALSE
prior_plot_df <- prior_gene_table |>
    filter(Methylation_signal) |>
    mutate(Gene = reorder(Gene, CMEnt_DMRs))

if (nrow(prior_plot_df) > 0) {
    ggplot(prior_plot_df, aes(x = Gene, y = CMEnt_DMRs, fill = Theme)) +
        geom_col(width = 0.7) +
        coord_flip() +
        theme_minimal() +
        labs(title = "AML Genes Overlapping CMEnt DMRs", x = "", y = "CMEnt DMRs", fill = "")
}

0.9 GO and KEGG Enrichment

missMethyl performs methylation-array-aware enrichment for CMEnt DMRs while correcting for probe-number bias across genes.

aml_term_pattern <- paste(
    c(
        "acute myeloid", "leukemia", "leukaemia", "myeloid", "hematopoiet", "haematopoiet",
        "stem cell", "differentiation", "immune", "leukocyte", "lymphocyte", "granulocyte",
        "monocyte", "macrophage", "cytokine", "chemokine", "phagosome", "JAK", "STAT",
        "HOX", "FLT3", "NPM1", "DNA methylation", "apoptosis", "cell cycle",
        "transcriptional misregulation"
    ),
    collapse = "|"
)

normalize_missmethyl_result <- function(x, collection) {
    if (is.null(x) || nrow(x) == 0L) {
        return(NULL)
    }
    x <- as.data.frame(x)
    term_col <- intersect(c("Term", "TERM", "Description", "Pathway"), colnames(x))[1]
    fdr_col <- intersect(c("FDR", "adj.P.Val", "P.DE", "P.Value"), colnames(x))[1]
    p_col <- intersect(c("P.DE", "P.Value", "P.DE.weighted"), colnames(x))[1]
    de_col <- intersect(c("DE", "N_DE", "Count"), colnames(x))[1]
    n_col <- intersect(c("N", "Total", "Size"), colnames(x))[1]
    ont_col <- intersect(c("Ont", "Ontology", "Category"), colnames(x))[1]
    if (is.na(term_col) || is.na(fdr_col)) {
        return(NULL)
    }
    data.frame(
        Collection = collection,
        Term = as.character(x[[term_col]]),
        Ontology = if (!is.na(ont_col)) as.character(x[[ont_col]]) else collection,
        N = if (!is.na(n_col)) suppressWarnings(as.numeric(x[[n_col]])) else NA_real_,
        DE = if (!is.na(de_col)) suppressWarnings(as.numeric(x[[de_col]])) else NA_real_,
        PValue = if (!is.na(p_col)) suppressWarnings(as.numeric(x[[p_col]])) else NA_real_,
        FDR = suppressWarnings(as.numeric(x[[fdr_col]])),
        stringsAsFactors = FALSE
    )
}

missmethyl_long <- NULL
if (requireNamespace("missMethyl", quietly = TRUE) &&
    requireNamespace("IlluminaHumanMethylation450kanno.ilmn12.hg19", quietly = TRUE)) {
    library(IlluminaHumanMethylation450kanno.ilmn12.hg19)
    cached <- getBenchmarkFile("missmethyl_cment_enrichment_results.rds")
    if (file.exists(cached)) {
        missmethyl_long <- readRDS(cached)
    } else {
        missmethyl_long <- base::do.call(rbind, Filter(Negate(is.null), lapply(c("GO", "KEGG"), function(collection) {
            ret <- tryCatch(
                missMethyl::goregion(
                    regions = dmrs_cment,
                    all.cpg = rownames(locs),
                    collection = collection,
                    array.type = "450K",
                    plot.bias = FALSE,
                    prior.prob = TRUE
                ),
                error = function(e) {
                    warning(sprintf("missMethyl %s enrichment failed for CMEnt DMRs: %s", collection, e$message))
                    NULL
                }
            )
            normalize_missmethyl_result(ret, collection)
        })))
        saveRDS(missmethyl_long, cached)
    }
} else {
    cat("missMethyl or the 450K annotation package is required for GO/KEGG enrichment.\n")
}
if (!is.null(missmethyl_long) && nrow(missmethyl_long) > 0L) {
    missmethyl_long <- missmethyl_long[is.finite(missmethyl_long$FDR), , drop = FALSE]
    missmethyl_long$NegLog10FDR <- -log10(pmax(missmethyl_long$FDR, .Machine$double.xmin))
    missmethyl_long$AML_Context <- ifelse(grepl(aml_term_pattern, missmethyl_long$Term, ignore.case = TRUE), "AML-context term", "Other top term")

    missmethyl_top <- missmethyl_long |>
        group_by(Collection) |>
        arrange(FDR, .by_group = TRUE) |>
        slice_head(n = 10) |>
        ungroup()
    missmethyl_top$Term_Label <- short_label(missmethyl_top$Term, 70)
    missmethyl_top$Term_Collection <- factor(
        paste(missmethyl_top$Term_Label, missmethyl_top$Collection, sep = "___"),
        levels = rev(unique(paste(missmethyl_top$Term_Label, missmethyl_top$Collection, sep = "___")))
    )

    knitr::kable(
        missmethyl_top |>
            dplyr::select(Collection, Ontology, Term, N, DE, PValue, FDR, AML_Context) |>
            arrange(Collection, FDR),
        digits = 3,
        row.names = FALSE,
        caption = "Top missMethyl GO/KEGG enrichments from CMEnt DMRs"
    )
}

Table 5: Top missMethyl GO/KEGG enrichments from CMEnt DMRs
Collection Ontology Term N DE PValue FDR AML_Context
GO GO cell periphery 5528 2122 0 0.000 Other top term
GO GO system development 3248 1426 0 0.000 Other top term
GO GO multicellular organismal process 6251 2353 0 0.000 Other top term
GO GO anatomical structure development 4906 1970 0 0.000 Other top term
GO GO multicellular organism development 3760 1586 0 0.000 Other top term
GO GO developmental process 5445 2140 0 0.000 Other top term
GO GO nervous system development 2074 978 0 0.000 Other top term
GO GO plasma membrane 5086 1931 0 0.000 Other top term
GO GO cell-cell signaling 1146 546 0 0.000 Other top term
GO GO gated channel activity 298 183 0 0.000 Other top term
KEGG KEGG Neuroactive ligand-receptor interaction 341 180 0 0.000 Other top term
KEGG KEGG Neuroactive ligand signaling 192 120 0 0.000 Other top term
KEGG KEGG Cadherin signaling 392 185 0 0.000 Other top term
KEGG KEGG Nicotine addiction 36 30 0 0.000 Other top term
KEGG KEGG Calcium signaling pathway 238 129 0 0.000 Other top term
KEGG KEGG Cell adhesion molecule (CAM) interaction 144 77 0 0.000 Other top term
KEGG KEGG Type I diabetes mellitus 42 27 0 0.004 Other top term
KEGG KEGG Hormone signaling 209 93 0 0.007 Other top term
KEGG KEGG Signaling pathways regulating pluripotency of stem cells 138 74 0 0.007 AML-context term
KEGG KEGG Morphine addiction 88 52 0 0.007 Other top term
if (!is.null(missmethyl_long) && nrow(missmethyl_long) > 0L) {
    ggplot(missmethyl_top, aes(x = NegLog10FDR, y = Term_Collection, size = DE, color = AML_Context)) +
        geom_point(alpha = 0.9) +
        facet_wrap(~Collection, scales = "free_y") +
        scale_y_discrete(labels = function(x) sub("___.*$", "", x)) +
        scale_color_manual(values = c("AML-context term" = "#B8405E", "Other top term" = "grey50")) +
        theme_minimal() +
        theme(axis.text.y = element_text(size = 7)) +
        labs(title = "missMethyl Enrichment", x = expression(-log[10]("FDR")), y = "", color = "", size = "DM genes")
} else {
    cat("missMethyl returned no enrichment results.\n")
}

focused_terms <- if (!is.null(missmethyl_long) && nrow(missmethyl_long) > 0L) {
    missmethyl_long |>
        filter(grepl(aml_term_pattern, Term, ignore.case = TRUE)) |>
        group_by(Collection) |>
        arrange(FDR, .by_group = TRUE) |>
        slice_head(n = 8) |>
        ungroup()
} else {
    data.frame()
}

if (nrow(focused_terms) > 0L) {
    focused_terms$Term_Label <- short_label(focused_terms$Term, 62)
    focused_terms$Term_Collection <- factor(
        paste(focused_terms$Term_Label, focused_terms$Collection, sep = "___"),
        levels = rev(unique(paste(focused_terms$Term_Label, focused_terms$Collection, sep = "___")))
    )
    knitr::kable(
        focused_terms |>
            dplyr::select(Collection, Ontology, Term, N, DE, PValue, FDR) |>
            arrange(Collection, FDR),
        digits = 3,
        row.names = FALSE,
        caption = "Top AML-relevant GO/KEGG terms"
    )
}

Table 6: Top AML-relevant GO/KEGG terms
Collection Ontology Term N DE PValue FDR
GO GO cell differentiation 3702 1479 0.000 0.000
GO GO neuron differentiation 1112 534 0.000 0.000
GO GO positive regulation of cell differentiation 738 334 0.000 0.000
GO GO central nervous system neuron differentiation 115 76 0.000 0.000
GO GO regulation of cell differentiation 1331 545 0.000 0.000
GO GO muscle cell differentiation 350 166 0.000 0.000
GO GO striated muscle cell differentiation 263 123 0.000 0.002
GO GO regulation of neuron differentiation 114 65 0.000 0.004
KEGG KEGG Signaling pathways regulating pluripotency of stem cells 138 74 0.000 0.007
KEGG KEGG Autoimmune thyroid disease 39 21 0.003 0.063
KEGG KEGG Hematopoietic cell lineage 90 37 0.013 0.138
KEGG KEGG Cytokine-cytokine receptor interaction 258 84 0.020 0.186
KEGG KEGG Intestinal immune network for IgA production 45 20 0.032 0.282
KEGG KEGG Viral protein interaction with cytokine and cytokine receptor 89 26 0.161 0.716
KEGG KEGG Chemokine signaling pathway 181 54 0.834 1.000
KEGG KEGG Cell cycle 153 22 1.000 1.000
if (nrow(focused_terms) > 0L) {
    ggplot(focused_terms, aes(x = -log10(pmax(FDR, .Machine$double.xmin)), y = Term_Collection, fill = Collection)) +
        geom_col(width = 0.7) +
        facet_wrap(~Collection, scales = "free_y") +
        scale_y_discrete(labels = function(x) sub("___.*$", "", x)) +
        theme_minimal() +
        theme(axis.text.y = element_text(size = 8), legend.position = "none") +
        labs(title = "AML-Relevant Enrichment Terms", x = expression(-log[10]("FDR")), y = "")
} else {
    cat("No missMethyl terms matched the AML-focused keyword set.\n")
}

0.10 Candidate CMEnt Gene Overlapping Loci

dmr_table <- as.data.frame(dmrs_cment)
dmr_table$DMR <- paste0(dmr_table$seqnames, ":", dmr_table$start, "-", dmr_table$end)
dmr_table$delta_beta_for_ranking <- dmr_delta
dmr_table$abs_delta_beta <- abs(dmr_delta)
dmr_table$svm_score_for_ranking <- if ("score" %in% colnames(dmr_table)) dmr_table$score else 0
if (!"qval" %in% colnames(dmr_table)) {
    dmr_table$qval <- NA_real_
}
if (!"pval" %in% colnames(dmr_table)) {
    dmr_table$pval <- NA_real_
}
if (!"score" %in% colnames(dmr_table)) {
    dmr_table$score <- NA_real_
}

top_dmrs <- dmr_table |>
    filter(has_text(in_promoter_of) | has_text(in_gene_body_of)) |>
    arrange(desc(svm_score_for_ranking), qval, desc(abs_delta_beta)) |>
    dplyr::select(
        DMR,
        width,
        score,
        qval,
        pval,
        delta_beta_for_ranking,
        any_of(c("delta_beta_promoter", "delta_beta_gene_body", "seeds_num", "sites_num", "in_promoter_of", "in_gene_body_of"))
    ) |>
    head(20)

knitr::kable(top_dmrs, digits = 4, caption = "Top 20 promoter or gene-body overlapping CMEnt DMRs ranked by score")

Table 7: Top 20 promoter or gene-body overlapping CMEnt DMRs ranked by score
DMR width score qval pval delta_beta_for_ranking delta_beta_promoter delta_beta_gene_body seeds_num sites_num in_promoter_of in_gene_body_of
chr1:cg14278300-cg09554443 chr1:167486978-167487762 785 0.6566 0e+00 0e+00 -0.0627 -0.3938 -0.0627 2 5 CD247 CD247
chr8:cg25247520-cg00780520 chr8:128808017-128808554 538 0.6352 0e+00 0e+00 -0.3510 -0.3603 -0.3395 3 3 PVT1 PVT1
chr21:cg05126444-cg16704958 chr21:38629859-38630728 870 0.6281 0e+00 0e+00 -0.1452 NA -0.1452 2 5 NA VPS26C
chr17:cg09489844-cg10168457 chr17:79880647-79882876 2230 0.6262 0e+00 0e+00 -0.0552 -0.0020 -0.0020 3 10 MAFG-AS1,MAFG,SIRT7,MILIP MAFG-AS1,MAFG,MILIP
chr10:cg10770832-cg09622269 chr10:76803270-76803925 656 0.6242 0e+00 0e+00 0.2904 NA 0.2755 5 5 NA DUSP29
chr19:cg24291974-cg19417168 chr19:4531638-4531961 324 0.6166 0e+00 0e+00 -0.4472 NA -0.3740 4 4 NA PLIN5
chr11:cg26512142-cg05898618 chr11:2554198-2555576 1379 0.6147 0e+00 0e+00 -0.0686 NA -0.0520 4 11 NA KCNQ1
chr16:cg05673293-cg07605834 chr16:71475279-71475926 648 0.6109 0e+00 0e+00 0.4046 0.0978 0.4250 4 5 TLE7 TLE7
chr10:cg19007269-cg13564061 chr10:105420501-105421480 980 0.6092 0e+00 0e+00 -0.2460 -0.3165 -0.2708 4 6 SH3PXD2A SH3PXD2A
chr11:cg18431910-cg13228701 chr11:78614239-78614522 284 0.6091 1e-04 1e-04 0.2831 NA 0.2831 2 3 NA TENM4
chr7:cg01572810-cg16810272 chr7:150901654-150902685 1032 0.6061 0e+00 0e+00 0.3312 -0.0022 0.3526 2 3 DRC11L DRC11L
chr6:cg11805138-cg23457357 chr6:31148332-31148748 417 0.6030 0e+00 0e+00 -0.0579 -0.0563 -0.0563 11 15 POU5F1 PSORS1C3,POU5F1
chr17:cg11252953-cg21465176 chr17:80358829-80358876 48 0.5986 0e+00 0e+00 -0.0269 NA -0.0269 2 3 NA OGFOD3
chr2:cg03322446-cg24601559 chr2:43327014-43328536 1523 0.5967 0e+00 0e+00 0.3097 NA 0.3041 6 7 NA LINC02580,LINC01819
chr3:cg21463380-cg21526749 chr3:187389127-187389513 387 0.5967 0e+00 0e+00 -0.0854 -0.0854 NA 2 3 SST NA
chr11:cg20244273-cg01607369 chr11:7597349-7598673 1325 0.5955 0e+00 0e+00 -0.2169 -0.3501 -0.1600 2 5 PPFIBP2 PPFIBP2
chr17:cg26118142-cg16810621 chr17:3289363-3290164 802 0.5938 0e+00 0e+00 0.1574 0.0763 0.0763 3 6 OR3A2,OR1R1 OR3A2,OR1R1
chr11:cg10321236-cg03908908 chr11:76849101-76849564 464 0.5938 0e+00 0e+00 0.2971 0.3106 0.3313 4 4 MYO7A MYO7A
chr15:cg21819984-cg08428878 chr15:101084507-101085341 835 0.5930 0e+00 0e+00 0.2879 0.3293 0.3515 7 8 CERS3 CERS3
chr1:cg16104450-cg06882058 chr1:243645911-243646787 877 0.5923 0e+00 0e+00 -0.1044 NA -0.1044 2 7 NA SDCCAG8

0.11 Top CMEnt DMR Visualization

CMEnt::plotDMRs(
    dmrs_cment,
    top_n = 1,
    score_by = "score",
    beta = beta_handler,
    pheno = pheno,
    sample_group_col = sample_group_col,
    genome = "hg19",
    array = array_type
)

0.12 CMEnt DMR Manhattan Plot

CMEnt::plotDMRsManhattan(
    dmrs_cment,
    genome = "hg19")

0.13 CMEnt DMR Interaction Circos Visualization

CMEnt::plotDMRsCircos(
    dmrs_cment,
    genome = "hg19",
    array = array_type
)

0.14 Insights and Interpretation

This CMEnt re-analysis of GSE63409 extends the original Hu et al.  study from a gene-level methylation and expression biomarker analysis into a region-level interpretation of AML-associated methylation architecture. Whereas the original publication integrated methylation and expression data to nominate AML-relevant pathways and three prognostic genes, ATP11A, ITGAM, and ZNRF2, this notebook shows that the same methylation dataset contains a broad and spatially coherent regional signal: 72,556 significant DMPs were assembled into 8,654 CMEnt DMRs, covering about 15.1 Mb of the genome, with a slight excess of hypermethylated regions in AML.

A main new observation is that the regional signal is not randomly distributed across gene annotation space. Most CMEnt DMRs overlap annotated genes, especially gene bodies, and many overlap both promoter and gene-body annotations. This suggests that AML-associated methylation changes in this dataset are not limited to isolated promoter CpGs, but frequently form extended regulatory blocks spanning transcriptional units. The effect-size plot further indicates that both promoter-overlapping and gene-body-overlapping DMRs contain clear hypermethylated and hypomethylated subclasses, with gene-body DMRs contributing the larger number of region-level events.

Although significant DMPs are most frequent in OpenSea regions, CpGs retained inside CMEnt DMRs are strongly enriched in CpG islands and shores. This indicates that CMEnt preferentially captures locally coherent methylation changes in CpG-dense regulatory neighborhoods, rather than simply preserving the genome-wide distribution of significant single CpGs. In practical terms, the analysis reframes part of the AML methylation signal as coordinated regional dysregulation around CpG island-associated loci.

The targeted AML gene scan also supports biological relevance while adding positional detail. CMEnt DMRs overlap several AML-associated regulatory and differentiation genes, including HOXA9, HOXA10, RUNX1, STAT3, CD34, and GATA2. This partly recapitulates the original study’s emphasis on hematopoietic differentiation and AML-relevant signaling, but adds information about whether these signals occur as promoter, gene-body, or mixed regional methylation events. Notably, RUNX1 and STAT3 show strong hypomethylated DMR signals, while HOXA10 and CD34 show hypermethylated regional signals, suggesting that AML-associated methylation changes are directionally heterogeneous across disease-relevant loci.

The enrichment results further reinforce the biological interpretation. The strongest GO terms are broad developmental, cell-periphery, cell-signaling, and differentiation categories, while AML-context terms include cell differentiation, regulation of differentiation, stem-cell pluripotency signaling, hematopoietic cell lineage, and cytokine-related pathways. Compared with the original study’s pathway-level analysis, CMEnt adds the observation that these biological themes are supported by coherent DMR structures rather than only by individually significant CpGs or methylation-expression gene intersections.

Finally, the candidate-region and visualization figures provide concrete follow-up loci. The top-scoring DMR overlaps CD247 on chromosome 1, shows clear group separation with cross-validation accuracy of 0.85, and is hypomethylated in AML. Other high-ranking regions include PVT1, RUNX1-associated regulatory candidates through the AML scan, POU5F1, SH3PXD2A, TLE7, KCNQ1, PLIN5, and MAFG/SIRT7-associated loci. The Manhattan and circos plots show that high-scoring DMRs are distributed across many chromosomes, with 115 identified DMR blocks and recurrent motif-interaction patterns involving factors such as KLF-family motifs and AHR::ARNT-like motifs.

Overall, this analysis supports the original conclusion that AML is associated with dysregulated methylation in genes and pathways linked to hematopoietic differentiation, immune signaling, and development. Its main added value is that it converts the single-CpG signal into interpretable regional methylation structures, revealing CpG island-enriched DMR organization, promoter and gene-body-specific effect patterns, and candidate loci that can be prioritized for biological validation.

0.15 Session Info

sessionInfo()

R version 4.6.0 (2026-04-24) Platform: x86_64-pc-linux-gnu Running under: Ubuntu 24.04.4 LTS

Matrix products: default BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.12.0 LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0 LAPACK version 3.12.0

locale: [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

time zone: Europe/Brussels tzcode source: system (glibc)

attached base packages: [1] parallel stats4 stats graphics grDevices datasets utils
[8] methods base

other attached packages: [1] IlluminaHumanMethylation450kanno.ilmn12.hg19_0.6.1 [2] scales_1.4.0
[3] CMEnt_0.99.0
[4] IlluminaHumanMethylationEPICanno.ilm10b4.hg19_0.6.0 [5] org.Hs.eg.db_3.23.1
[6] TxDb.Hsapiens.UCSC.hg19.knownGene_3.22.1
[7] GenomicFeatures_1.64.0
[8] AnnotationDbi_1.74.0
[9] bsseq_1.48.0
[10] dplyr_1.2.1
[11] ggplot2_4.0.3
[12] data.table_1.18.4
[13] minfi_1.58.0
[14] bumphunter_1.54.0
[15] locfit_1.5-9.12
[16] iterators_1.0.14
[17] foreach_1.5.2
[18] Biostrings_2.80.1
[19] XVector_0.52.0
[20] SummarizedExperiment_1.42.0
[21] Biobase_2.72.0
[22] MatrixGenerics_1.24.0
[23] matrixStats_1.5.0
[24] GenomicRanges_1.64.0
[25] Seqinfo_1.2.0
[26] IRanges_2.46.0
[27] S4Vectors_0.50.1
[28] BiocGenerics_0.58.1
[29] generics_0.1.4
[30] testthat_3.3.2
[31] BiocStyle_2.40.0

loaded via a namespace (and not attached): [1] graph_1.90.0
[2] igraph_2.3.2
[3] plotly_4.12.0
[4] ChAMPdata_2.44.0
[5] Formula_1.2-5
[6] devtools_2.5.2
[7] tidyselect_1.2.1
[8] bit_4.6.0
[9] doParallel_1.0.17
[10] clue_0.3-68
[11] lattice_0.22-9
[12] rjson_0.2.23
[13] nor1mix_1.3-3
[14] blob_1.3.0
[15] stringr_1.6.0
[16] rngtools_1.5.2
[17] S4Arrays_1.12.0
[18] base64_2.0.2
[19] dichromat_2.0-0.1
[20] scrime_1.3.7
[21] seqLogo_1.78.0
[22] png_0.1-9
[23] tinytex_0.59
[24] ggplotify_0.1.3
[25] cli_3.6.6
[26] marray_1.90.0
[27] bedr_1.1.5
[28] outliers_0.15
[29] ProtGenerics_1.44.0
[30] askpass_1.2.1
[31] multtest_2.68.0
[32] openssl_2.4.2
[33] JADE_2.0-4
[34] nleqslv_3.3.7
[35] pkgdown_2.2.0
[36] textshaping_1.0.5
[37] BiocIO_1.22.0
[38] purrr_1.2.2
[39] dendextend_1.19.1
[40] curl_7.1.0
[41] tidytree_0.4.7
[42] mime_0.13
[43] evaluate_1.0.5
[44] wateRmelon_2.18.0
[45] ComplexHeatmap_2.28.0
[46] stringi_1.8.7
[47] backports_1.5.1
[48] desc_1.4.3
[49] XML_3.99-0.23
[50] httpuv_1.6.17
[51] clusterProfiler_4.20.0
[52] magrittr_2.0.5
[53] rappdirs_0.3.4
[54] splines_4.6.0
[55] mclust_6.1.2
[56] DelayedDataFrame_1.28.0
[57] BiasedUrn_2.0.12
[58] jpeg_0.1-11
[59] doRNG_1.8.6.3
[60] ggraph_2.2.2
[61] rentrez_1.2.4
[62] IlluminaHumanMethylation450kmanifest_0.4.0 [63] DT_0.34.0
[64] sessioninfo_1.2.4
[65] DBI_1.3.0
[66] HDF5Array_1.40.0
[67] reactome.db_1.96.0
[68] jquerylib_0.1.4
[69] genefilter_1.94.0
[70] withr_3.0.2
[71] systemfonts_1.3.2
[72] class_7.3-23
[73] enrichplot_1.32.0
[74] rprojroot_2.1.1
[75] ggnewscale_0.5.2
[76] brio_1.1.5
[77] tidygraph_1.3.1
[78] sva_3.60.0
[79] isva_1.10
[80] formatR_1.14
[81] rtracklayer_1.72.0
[82] BiocManager_1.30.27
[83] Illumina450ProbeVariants.db_1.48.0
[84] htmlwidgets_1.6.4
[85] fs_2.1.0
[86] ggrepel_0.9.8
[87] biomaRt_2.68.0
[88] missMethyl_1.46.0
[89] labeling_0.4.3
[90] SparseArray_1.12.2
[91] cellranger_1.1.0
[92] shinycssloaders_1.1.0
[93] h5mread_1.4.0
[94] annotate_1.90.0
[95] VariantAnnotation_1.58.0
[96] knitr_1.51
[97] TFBSTools_1.50.0
[98] UCSC.utils_1.8.0
[99] beanplot_1.3.1
[100] TFMPvalue_1.0.0
[101] ChAMP_2.42.0
[102] annotatr_1.38.0
[103] patchwork_1.3.2
[104] caTools_1.18.3
[105] grid_4.6.0
[106] ggtree_4.2.0
[107] rhdf5_2.56.0
[108] pwalign_1.8.0
[109] R.oo_1.27.1
[110] ggiraph_0.9.6
[111] regioneR_1.44.0
[112] gridGraphics_0.5-1
[113] ellipsis_0.3.3
[114] lazyeval_0.2.3
[115] yaml_2.3.12
[116] survival_3.8-6
[117] RPMM_1.25
[118] BiocVersion_3.23.1
[119] crayon_1.5.3
[120] tweenr_2.0.3
[121] RColorBrewer_1.1-3
[122] tidyr_1.3.2
[123] later_1.4.8
[124] codetools_0.2-20
[125] base64enc_0.1-6
[126] GlobalOptions_0.1.4
[127] KEGGREST_1.52.0
[128] shape_1.4.6.1
[129] ReactomePA_1.56.0
[130] fastICA_1.2-7
[131] limma_3.68.4
[132] gdtools_0.5.1
[133] Rsamtools_2.28.0
[134] filelock_1.0.3
[135] showtext_0.9-8
[136] foreign_0.8-90
[137] pkgconfig_2.0.3
[138] xml2_1.5.2
[139] GenomicAlignments_1.48.0
[140] aplot_0.2.9
[141] hummingbird_1.22.0
[142] ape_5.8-1
[143] BSgenome_1.80.0
[144] viridisLite_0.4.3
[145] biovizBase_1.60.0
[146] gridBase_0.4-7
[147] xtable_1.8-8
[148] interp_1.1-6
[149] lumi_2.64.0
[150] plyr_1.8.9
[151] httr_1.4.8
[152] tools_4.6.0
[153] pkgbuild_1.4.8
[154] htmlTable_2.5.0
[155] checkmate_2.3.4
[156] nlme_3.1-168
[157] affy_1.90.0
[158] futile.logger_1.4.9
[159] lambda.r_1.2.4
[160] dbplyr_2.5.2
[161] ExperimentHub_3.2.0
[162] IlluminaHumanMethylationEPICmanifest_0.3.0 [163] digest_0.6.39
[164] permute_0.9-10
[165] bookdown_0.46
[166] Matrix_1.7-5
[167] farver_2.1.2
[168] tzdb_0.5.0
[169] AnnotationFilter_1.36.0
[170] reshape2_1.4.5
[171] yulab.utils_0.2.4
[172] viridis_0.6.5
[173] DirichletMultinomial_1.54.0
[174] rpart_4.1.27
[175] glue_1.8.1
[176] cachem_1.1.0
[177] bspm_0.5.8
[178] VennDiagram_1.8.2
[179] BiocFileCache_3.2.0
[180] polyclip_1.10-7
[181] methylumi_2.58.0
[182] Hmisc_5.2-5
[183] txdbmaker_1.8.0
[184] sysfonts_0.8.9
[185] pkgload_1.5.2
[186] statmod_1.5.2
[187] impute_1.86.0
[188] fontBitstreamVera_0.1.1
[189] GEOquery_2.80.0
[190] httr2_1.2.2
[191] showtextdb_3.0
[192] gson_0.1.0
[193] dmrseq_1.32.0
[194] graphlayouts_1.2.3
[195] siggenes_1.86.0
[196] gtools_3.9.5
[197] readxl_1.5.0
[198] preprocessCore_1.74.0
[199] affyio_1.82.0
[200] gridExtra_2.3
[201] shiny_1.13.0
[202] tidydr_0.0.6
[203] R.utils_2.13.0
[204] rhdf5filters_1.24.0
[205] RCurl_1.98-1.19
[206] memoise_2.0.1
[207] rmarkdown_2.31
[208] R.methodsS3_1.8.2
[209] svglite_2.2.2
[210] reshape_0.8.10
[211] fontLiberation_0.1.0
[212] illuminaio_0.54.0
[213] rstudioapi_0.18.0
[214] cluster_2.1.8.2
[215] ROC_1.88.0
[216] hms_1.1.4
[217] globaltest_5.66.0
[218] DMRcate_3.8.0
[219] colorspace_2.1-2
[220] FNN_1.1.4.1
[221] rlang_1.2.0
[222] quadprog_1.5-8
[223] BSgenome.Hsapiens.UCSC.hg19_1.4.3
[224] GenomeInfoDb_1.48.0
[225] DelayedMatrixStats_1.34.0
[226] sparseMatrixStats_1.24.0
[227] shinythemes_1.2.0
[228] ggforce_0.5.0
[229] ggtangle_0.1.2
[230] circlize_0.4.18
[231] mgcv_1.9-4
[232] xfun_0.58
[233] ggseqlogo_0.2.2
[234] e1071_1.7-17
[235] aisdk_1.4.12
[236] abind_1.4-8
[237] GOSemSim_2.38.0
[238] tibble_3.3.1
[239] treeio_1.36.1
[240] Rhdf5lib_2.0.0
[241] readr_2.2.0
[242] futile.options_1.0.1
[243] bitops_1.0-9
[244] ps_1.9.3
[245] promises_1.5.0
[246] scatterpie_0.2.6
[247] inline_0.3.21
[248] RSQLite_3.53.1
[249] qvalue_2.44.0
[250] DelayedArray_0.38.2
[251] proxy_0.4-29
[252] GO.db_3.23.1
[253] compiler_4.6.0
[254] prettyunits_1.2.0
[255] beachmat_2.28.0
[256] graphite_1.58.0
[257] Rcpp_1.1.1-1.1
[258] DNAcopy_1.86.0
[259] fontquiver_0.2.1
[260] edgeR_4.10.1
[261] AnnotationHub_4.2.0
[262] usethis_3.2.1
[263] MASS_7.3-65
[264] progress_1.2.3
[265] BiocParallel_1.46.0
[266] R6_2.6.1
[267] fastmap_1.2.0
[268] ensembldb_2.36.1
[269] enrichit_0.1.4
[270] nnet_7.3-20
[271] gtable_0.3.6
[272] KernSmooth_2.23-26
[273] strex_2.0.1
[274] latticeExtra_0.6-31
[275] deldir_2.0-4
[276] htmltools_0.5.9
[277] bit64_4.8.2
[278] lifecycle_1.0.5
[279] S7_0.2.2
[280] processx_3.9.0
[281] callr_3.8.0
[282] Gviz_1.56.0
[283] restfulr_0.0.16
[284] sass_0.4.10
[285] vctrs_0.7.3
[286] DOSE_4.6.0
[287] ggfun_0.2.0
[288] goseq_1.64.0
[289] bslib_0.11.0
[290] pillar_1.11.1
[291] magick_2.9.1
[292] otel_0.2.0
[293] combinat_0.0-8
[294] geneLenDataBase_1.48.0
[295] jsonlite_2.0.0
[296] cigarillo_1.2.0
[297] GetoptLong_1.1.1