## ----setup, include=FALSE-----------------------------------------------------
knitr::opts_chunk$set(
  collapse   = TRUE,
  comment    = "#>",
  warning    = FALSE,
  message    = FALSE,
  fig.width  = 7,
  fig.height = 5
)

## ----pipeline-overview, echo=FALSE, fig.cap="GExPipe 15-step pipeline. Each box corresponds to one sidebar tab in the Shiny app."----
pipeline <- data.frame(
  step  = 1:15,
  phase = rep(
    c("Data preparation", "Gene discovery",
      "Candidate refinement", "Clinical translation"),
    c(5, 3, 4, 3)
  ),
  label = c(
    "1 Download", "2 QC", "3 Normalize", "4 Groups", "5 Batch",
    "6 DE", "7 WGCNA", "8 Common genes",
    "9 PPI", "10 ML", "11 Validation", "12 ROC",
    "13 Nomogram", "14 GSEA", "15 Report"
  ),
  stringsAsFactors = FALSE
)
phase_cols <- c(
  "Data preparation"       = "#4E79A7",
  "Gene discovery"         = "#59A14F",
  "Candidate refinement" = "#F28E2B",
  "Clinical translation" = "#E15759"
)
pipeline$y <- rev(pipeline$step)
ggplot2::ggplot(pipeline, ggplot2::aes(x = 1, y = y, fill = phase)) +
  ggplot2::geom_tile(
    ggplot2::aes(width = 0.92, height = 0.88),
    colour = "white", linewidth = 0.4
  ) +
  ggplot2::geom_text(
    ggplot2::aes(label = label),
    colour = "white", size = 3.2, fontface = "bold"
  ) +
  ggplot2::scale_fill_manual(values = phase_cols, name = "Phase") +
  ggplot2::scale_x_continuous(limits = c(0.5, 1.5), expand = c(0, 0)) +
  ggplot2::scale_y_continuous(expand = c(0.02, 0.02)) +
  ggplot2::labs(x = NULL, y = NULL, title = "Shiny app workflow") +
  ggplot2::theme_void() +
  ggplot2::theme(
    legend.position = "bottom",
    plot.title = ggplot2::element_text(hjust = 0.5, face = "bold")
  )

## ----install-bioc, eval=FALSE-------------------------------------------------
# if (!requireNamespace("BiocManager", quietly = TRUE))
#     install.packages("BiocManager")
# 
# BiocManager::install("GExPipe", dependencies = TRUE)

## ----verify-bioc, eval=FALSE--------------------------------------------------
# library(GExPipe)
# packageVersion("GExPipe")

## ----install-github, eval=FALSE-----------------------------------------------
# options(timeout = 3600)
# 
# if (!requireNamespace("BiocManager", quietly = TRUE))
#     install.packages("BiocManager")
# options(repos = BiocManager::repositories())
# 
# if (!requireNamespace("remotes", quietly = TRUE))
#     install.packages("remotes")
# remotes::install_github(
#   "safarafique/GExPipe",
#   ref = "main",
#   dependencies = TRUE,
#   INSTALL_opts = "--no-staged-install"
# )

## ----install-annot, eval=FALSE------------------------------------------------
# if (!requireNamespace("BiocManager", quietly = TRUE)) install.packages("BiocManager")
# BiocManager::install(c("org.Hs.eg.db", "biomaRt"), ask = FALSE, update = FALSE)

## ----run-latest-github, eval=FALSE--------------------------------------------
# if (!requireNamespace("shiny", quietly = TRUE)) install.packages("shiny")
# if (!requireNamespace("pkgload", quietly = TRUE)) install.packages("pkgload")
# shiny::runGitHub(
#   "safarafique/GExPipe",
#   ref = "main",
#   subdir = "inst/shinyapp",
#   destdir = tempfile()
# )

## ----run-latest-local, eval=FALSE---------------------------------------------
# # Local clone
# setwd("path/to/GExPipe")
# pkgload::load_all(".")
# app <- GExPipe::runGExPipe(launch.browser = FALSE)
# shiny::runApp(app, port = 3838L)

## ----run-latest-reinstall, eval=FALSE-----------------------------------------
# remotes::install_github(
#   "safarafique/GExPipe",
#   ref = "main",
#   force = TRUE,
#   dependencies = TRUE,
#   INSTALL_opts = "--no-staged-install"
# )
# app <- GExPipe::runGExPipe(launch.browser = FALSE)
# shiny::runApp(app, port = 3838L)

## ----launch, eval=FALSE-------------------------------------------------------
# app <- GExPipe::runGExPipe()
# shiny::runApp(app, port = 3838L)

## ----launch-github-auto, eval=FALSE-------------------------------------------
# options(gexpipe.auto_install = TRUE)  # GitHub installs only
# app <- GExPipe::runGExPipe()
# shiny::runApp(app, port = 3838L)

## ----step01-screenshot, echo=FALSE, fig.cap="Step 1: Select platform, dataset mode, DE method, and GSE IDs.", out.width="100%"----
knitr::include_graphics("images/step01_download.png")

## ----step02a-screenshot, echo=FALSE, fig.cap="Step 2a: Venn and UpSet gene overlap.", out.width="100%"----
knitr::include_graphics("images/step02a_qc.png")

## ----step02b-screenshot, echo=FALSE, fig.cap="Step 2b: Raw expression boxplot.", out.width="100%"----
knitr::include_graphics("images/step02b_qc.png")

## ----step02c-screenshot, echo=FALSE, fig.cap="Step 2c: PCA and connectivity outlier detection.", out.width="100%"----
knitr::include_graphics("images/step02c_qc.png")

## ----step03a-screenshot, echo=FALSE, fig.cap="Step 3a: Overall density and Q-Q plots after normalization.", out.width="100%"----
knitr::include_graphics("images/step03a_normalize.png")

## ----step03b-screenshot, echo=FALSE, fig.cap="Step 3b: Median/range alignment and distribution overlap.", out.width="100%"----
knitr::include_graphics("images/step03b_normalize.png")

## ----step04a-screenshot, echo=FALSE, fig.cap="Step 4a: Select phenotype column per GSE.", out.width="100%"----
knitr::include_graphics("images/step04a_groups.png")

## ----step04b-screenshot, echo=FALSE, fig.cap="Step 4b: Group Summary after Apply Categorization.", out.width="100%"----
knitr::include_graphics("images/step04b_groups.png")

## ----step05a-screenshot, echo=FALSE, fig.cap="Step 5a: Variance filtering and batch correction method.", out.width="100%"----
knitr::include_graphics("images/step05a_batch.png")

## ----step05b-screenshot, echo=FALSE, fig.cap="Step 5b: PCA by dataset before and after batch correction.", out.width="100%"----
knitr::include_graphics("images/step05b_batch.png")

## ----step06a-screenshot, echo=FALSE, fig.cap="Step 6a: DE parameters, statistical model, and pipeline verification.", out.width="100%"----
knitr::include_graphics("images/step06a_de.png")

## ----step06b-screenshot, echo=FALSE, fig.cap="Step 6b: Volcano plot and top DEG table.", out.width="100%"----
knitr::include_graphics("images/step06b_de.png")

## ----step07a-screenshot, echo=FALSE, fig.cap="Step 7a: WGCNA data preparation and gene selection.", out.width="100%"----
knitr::include_graphics("images/step07a_wgcna.png")

## ----step07b-screenshot, echo=FALSE, fig.cap="Step 7b: Soft-threshold power selection.", out.width="100%"----
knitr::include_graphics("images/step07b_wgcna.png")

## ----step07c-screenshot, echo=FALSE, fig.cap="Step 7c: Module dendrogram and module-trait heatmap.", out.width="100%"----
knitr::include_graphics("images/step07c_wgcna.png")

## ----step07d-screenshot, echo=FALSE, fig.cap="Step 7d: Significant modules and hub gene summary.", out.width="100%"----
knitr::include_graphics("images/step07d_wgcna.png")

## ----step08a-screenshot, echo=FALSE, fig.cap="Step 8a: Common genes Venn diagram (DEG intersect WGCNA).", out.width="100%"----
knitr::include_graphics("images/step08a_common_genes.png")

## ----step08b-screenshot, echo=FALSE, fig.cap="Step 8b: GO enrichment of common genes.", out.width="100%"----
knitr::include_graphics("images/step08b_go.png")

## ----step08c-screenshot, echo=FALSE, fig.cap="Step 8c: KEGG enrichment of common genes.", out.width="100%"----
knitr::include_graphics("images/step08c_kegg.png")

## ----step09a-screenshot, echo=FALSE, fig.cap="Step 9a: Run PPI and interactive vs non-interactive gene table.", out.width="100%"----
knitr::include_graphics("images/step09a_ppi.png")

## ----step09b-screenshot, echo=FALSE, fig.cap="Step 9b: PPI network graph and hub gene metrics.", out.width="100%"----
knitr::include_graphics("images/step09b_ppi.png")

## ----step10a-screenshot, echo=FALSE, fig.cap="Step 10a: Select ML methods and run analysis.", out.width="100%"----
knitr::include_graphics("images/step10a_ml.png")

## ----step10b-screenshot, echo=FALSE, fig.cap="Step 10b: Method overlap Venn diagram and common ML genes.", out.width="100%"----
knitr::include_graphics("images/step10b_ml.png")

## ----step11a-screenshot, echo=FALSE, fig.cap="Step 11a: Validation mode and external validation settings.", out.width="100%"----
knitr::include_graphics("images/step11a_validation.png")

## ----step11b-screenshot, echo=FALSE, fig.cap="Step 11b: External validation DE results.", out.width="100%"----
knitr::include_graphics("images/step11b_validation_external.png")

## ----step12a-screenshot, echo=FALSE, fig.cap="Step 12a: Training ROC curves and AUC summary.", out.width="100%"----
knitr::include_graphics("images/step12a_roc.png")

## ----step12b-screenshot, echo=FALSE, fig.cap="Step 12b: Training vs validation AUC comparison.", out.width="100%"----
knitr::include_graphics("images/step12b_roc.png")

## ----step13-screenshot, echo=FALSE, fig.cap="Step 13: Nomogram, calibration, and decision curves.", out.width="100%"----
knitr::include_graphics("images/step13_nomogram.png")

## ----step14-screenshot, echo=FALSE, fig.cap="Step 14: GSEA enrichment plots per signature gene.", out.width="100%"----
knitr::include_graphics("images/step14_gsea.png")

## ----step15-screenshot, echo=FALSE, fig.cap="Step 15: Results summary overview.", out.width="100%"----
knitr::include_graphics("images/step15_summary.png")

## ----id-formats---------------------------------------------------------------
library(GExPipe)

detect_fmt <- getFromNamespace("detect_gene_id_format", "GExPipe")
need_conv <- getFromNamespace("gexpipe_ids_need_symbol_conversion", "GExPipe")

examples <- list(
  "HGNC symbols"              = c("TP53", "BRCA1", "EGFR"),
  "Arraystar / custom probes" = c("(+)E1A_r60_1", "ASHGV40000001"),
  "Affymetrix Ensembl probes" = c("ENSG00000000003_at", "ENSG00000000005_at"),
  "GenBank accessions"        = c("AB000409", "AB000463", "AB000781")
)

id_table <- data.frame(
  Example = names(examples),
  Detected_format = vapply(examples, detect_fmt, character(1)),
  Needs_symbol_conversion = vapply(examples, need_conv, logical(1)),
  check.names = FALSE
)
knitr::kable(id_table, caption = "How GExPipe classifies common GEO row ID types.")

## ----id-overlap-demo----------------------------------------------------------
genes <- c("TP53", "BRCA1", "EGFR", "MYC", "GAPDH", "ACTB")
set.seed(11)
m1 <- matrix(abs(rnorm(length(genes) * 4)), nrow = length(genes),
             dimnames = list(genes, paste0("GSE1_S", 1:4)))
m2 <- matrix(abs(rnorm(length(genes) * 4)), nrow = length(genes),
             dimnames = list(genes, paste0("GSE2_S", 1:4)))

overlap_out <- gexp_download_normalize_ids_for_overlap(
  micro_expr_list = list(GSE1 = m1, GSE2 = m2),
  rna_counts_list = list()
)
fin <- gexp_download_finalize_common_genes(
  micro_expr_list = overlap_out$micro_expr_list,
  rna_counts_list = overlap_out$rna_counts_list,
  all_genes_list  = overlap_out$all_genes_list
)
cat(
  overlap_out$log_text,
  "\nCommon genes after merge:", length(fin$common_genes), "\n"
)

## ----load-data----------------------------------------------------------------
library(ggplot2)

expr_tab <- read.csv(
  system.file("extdata", "vignette_expression.csv", package = "GExPipe"),
  check.names = FALSE, stringsAsFactors = FALSE
)
meta_tab <- read.csv(
  system.file("extdata", "vignette_sample_metadata.csv", package = "GExPipe"),
  check.names = FALSE, stringsAsFactors = FALSE
)

expr <- as.matrix(expr_tab[, -1L, drop = FALSE])
storage.mode(expr) <- "numeric"
rownames(expr) <- expr_tab[[1L]]

rownames(meta_tab) <- meta_tab$SampleID
meta_tab <- meta_tab[colnames(expr), , drop = FALSE]

dim(expr)
head(meta_tab)

## ----normalize----------------------------------------------------------------
if (!"Dataset" %in% colnames(meta_tab))
    meta_tab$Dataset <- "D1"

datasets <- unique(meta_tab$Dataset)
micro_expr_list <- setNames(
    lapply(datasets, function(ds) {
        ids <- rownames(meta_tab)[meta_tab$Dataset == ds]
        expr[, ids, drop = FALSE]
    }),
    datasets
)

norm_res <- gexp_normalize_and_intersect(
    micro_expr_list    = micro_expr_list,
    rna_counts_list    = list(),
    micro_norm_method  = "quantile",
    rnaseq_norm_method = "TMM",
    de_method          = "limma"
)

cat("Combined matrix :", paste(dim(norm_res$combined_expr), collapse = " x "), "\n")
cat("Common genes    :", length(norm_res$common_genes), "\n")

## ----pca-plot-----------------------------------------------------------------
expr_pca <- norm_res$combined_expr
keep     <- apply(expr_pca, 1L, var, na.rm = TRUE) > 1e-8
pca      <- prcomp(t(expr_pca[keep, ]), center = TRUE, scale. = TRUE)

pca_df <- data.frame(
    PC1     = pca$x[, 1L],
    PC2     = pca$x[, 2L],
    Dataset = meta_tab[rownames(pca$x), "Dataset"],
    stringsAsFactors = FALSE
)
var_pct <- round(summary(pca)$importance[2L, 1L:2L] * 100, 1)

ggplot(pca_df, aes(PC1, PC2, colour = Dataset)) +
    geom_point(size = 3) +
    theme_minimal() +
    labs(
        title    = "PCA - bundled example data",
        subtitle = "After quantile normalization and gene intersection",
        x        = paste0("PC1 (", var_pct[1L], "% variance)"),
        y        = paste0("PC2 (", var_pct[2L], "% variance)")
    )

## ----heatmap-plot-------------------------------------------------------------
top_var <- head(
    order(apply(norm_res$combined_expr, 1L, var, na.rm = TRUE),
          decreasing = TRUE),
    min(30L, nrow(norm_res$combined_expr))
)

if (length(top_var) > 1L) {
    pheatmap::pheatmap(
        norm_res$combined_expr[top_var, , drop = FALSE],
        scale         = "row",
        show_rownames = length(top_var) <= 30L,
        main          = "Top 30 most variable genes - bundled example data"
    )
}

## ----windows-fix, eval=FALSE--------------------------------------------------
# options(download.file.method = "wininet")
# unlink(
#     list.files(.libPaths()[1], pattern = "^00LOCK-", full.names = TRUE),
#     recursive = TRUE, force = TRUE
# )
# if (!requireNamespace("remotes", quietly = TRUE))
#     install.packages("remotes")
# remotes::install_github(
#   "safarafique/GExPipe",
#   ref = "main",
#   dependencies = TRUE,
#   INSTALL_opts = "--no-staged-install"
# )

## ----session-info-------------------------------------------------------------
sessionInfo()

