| Title: | GExPipe: Gene Expression Pipeline Shiny Application |
|---|---|
| Description: | Shiny application (GExPipe) for high-throughput genomic analysis of bulk RNA-seq and microarray data (e.g. from GEO). Integrates with Bioconductor (GEOquery, Biobase, limma, DESeq2, edgeR, clusterProfiler) for a single workflow: download, QC, normalization, batch correction, differential expression, WGCNA, pathway enrichment, PPI, and machine learning. Uses common data structures (ExpressionSet, DGEList) for interoperability. For a full dependency tree (including STRINGdb + PPI helpers), use BiocManager::install("GExPipe", dependencies = TRUE). STRING data are downloaded on first PPI use (internet required); they cannot be bundled in the package. Microarray CEL normalization uses affy and/or oligo when supplementary CEL files are available. |
| Authors: | Safa Rafique [aut, cre] (ORCID: <https://orcid.org/0000-0003-2646-8106>), Naeem Mahmood Ashraf [aut], Prof. Dr. Muhammad Farooq Sabar [aut] |
| Maintainer: | Safa Rafique <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.99.43 |
| Built: | 2026-07-22 16:17:52 UTC |
| Source: | https://github.com/bioc/GExPipe |
GExPipe users enter GSE accessions in the app; this helper runs
automatically during GEO download when a count file has no sample headers
(e.g. data.table::fread assigns V2, V3, ...). Columns are renamed
to GSM IDs from GEO pData so QC, normalization, and group selection see
individual samples (fixes issues such as a single V2 bar in outlier QC).
gexp_align_rnaseq_sample_names(count_matrix, metadata = NULL, gse_id = NULL)gexp_align_rnaseq_sample_names(count_matrix, metadata = NULL, gse_id = NULL)
count_matrix |
Numeric matrix (genes x samples). |
metadata |
Optional GEO pData with sample IDs as row names. |
gse_id |
GEO series accession (used for fallback naming). |
Matrix with improved column names.
# GSE137136-style: headerless columns after download, GSM IDs in metadata. mat <- matrix(1:4, nrow = 2, ncol = 2, dimnames = list(c("GENE1", "GENE2"), c("V2", "V3"))) meta <- data.frame(title = c("sample 1", "sample 2"), row.names = c("GSM111", "GSM222")) out <- gexp_align_rnaseq_sample_names(mat, meta, "GSE137136") colnames(out)# GSE137136-style: headerless columns after download, GSM IDs in metadata. mat <- matrix(1:4, nrow = 2, ncol = 2, dimnames = list(c("GENE1", "GENE2"), c("V2", "V3"))) meta <- data.frame(title = c("sample 1", "sample 2"), row.names = c("GSM111", "GSM222")) out <- gexp_align_rnaseq_sample_names(mat, meta, "GSE137136") colnames(out)
This helper wraps the Step 5 logic:
filters genes by a variance percentile,
applies one of several batch-correction methods,
reports gene reduction statistics.
gexp_batch_correct( expr, metadata, variance_percentile = 25, method = c("combat_ref", "sva", "limma", "combat", "quantile_limma", "hybrid") )gexp_batch_correct( expr, metadata, variance_percentile = 25, method = c("combat_ref", "sva", "limma", "combat", "quantile_limma", "hybrid") )
expr |
Combined expression matrix (genes x samples), after normalization. |
metadata |
Data.frame with at least columns |
variance_percentile |
Numeric between 0 and 50; bottom percentile to remove. |
method |
Batch method: one of "limma", "combat", "combat_ref", "quantile_limma", "hybrid", "sva". |
A list with elements:
expr_filtered |
filtered expression matrix before batch correction |
batch_corrected |
batch-corrected matrix |
genes_before |
integer, genes before filtering |
genes_after |
integer, genes after filtering |
filter_percent |
numeric, percent genes removed |
log_text |
character, human-readable log string |
expr <- matrix(rnorm(200), nrow = 20) rownames(expr) <- paste0("Gene", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) metadata <- data.frame( Dataset = rep(c("D1", "D2"), each = 5), Condition = rep(c("Normal", "Disease"), times = 5), row.names = colnames(expr), stringsAsFactors = FALSE ) out <- gexp_batch_correct(expr, metadata, variance_percentile = 10, method = "limma") dim(out$batch_corrected)expr <- matrix(rnorm(200), nrow = 20) rownames(expr) <- paste0("Gene", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) metadata <- data.frame( Dataset = rep(c("D1", "D2"), each = 5), Condition = rep(c("Normal", "Disease"), times = 5), row.names = colnames(expr), stringsAsFactors = FALSE ) out <- gexp_batch_correct(expr, metadata, variance_percentile = 10, method = "limma") dim(out$batch_corrected)
Finalize common genes and combined matrix after download/mapping
gexp_download_finalize_common_genes( micro_expr_list, rna_counts_list, all_genes_list )gexp_download_finalize_common_genes( micro_expr_list, rna_counts_list, all_genes_list )
micro_expr_list |
Named list of microarray matrices (genes x samples). |
rna_counts_list |
Named list of RNA-seq matrices (genes x samples). |
all_genes_list |
Named list of rowname vectors per dataset. |
List with updated lists, common_genes, combined_expr_raw, and status.
m1 <- matrix(1:12, nrow = 3, dimnames = list(c("A", "B", "C"), paste0("S", 1:4))) m2 <- matrix(1:12, nrow = 3, dimnames = list(c("B", "C", "D"), paste0("T", 1:4))) out <- gexp_download_finalize_common_genes( micro_expr_list = list(D1 = m1), rna_counts_list = list(D2 = m2), all_genes_list = list(D1 = rownames(m1), D2 = rownames(m2)) ) out$common_genesm1 <- matrix(1:12, nrow = 3, dimnames = list(c("A", "B", "C"), paste0("S", 1:4))) m2 <- matrix(1:12, nrow = 3, dimnames = list(c("B", "C", "D"), paste0("T", 1:4))) out <- gexp_download_finalize_common_genes( micro_expr_list = list(D1 = m1), rna_counts_list = list(D2 = m2), all_genes_list = list(D1 = rownames(m1), D2 = rownames(m2)) ) out$common_genes
Normalize dataset row IDs to gene symbols for overlap
gexp_download_normalize_ids_for_overlap( micro_expr_list, rna_counts_list, platform_per_gse = NULL, all_genes_list = NULL, micro_eset_list = NULL )gexp_download_normalize_ids_for_overlap( micro_expr_list, rna_counts_list, platform_per_gse = NULL, all_genes_list = NULL, micro_eset_list = NULL )
micro_expr_list |
Named list of microarray matrices. |
rna_counts_list |
Named list of RNA-seq matrices. |
platform_per_gse |
Optional named list/vector of GPL IDs. |
all_genes_list |
Optional prebuilt gene lists. |
micro_eset_list |
Optional named list of |
List with updated lists and appended log text.
m <- matrix(1:6, nrow = 2, dimnames = list(c("A", "B"), paste0("S", 1:3))) r <- matrix(1:6, nrow = 2, dimnames = list(c("B", "C"), paste0("T", 1:3))) out <- gexp_download_normalize_ids_for_overlap( micro_expr_list = list(M = m), rna_counts_list = list(R = r) ) names(out)m <- matrix(1:6, nrow = 2, dimnames = list(c("A", "B"), paste0("S", 1:3))) r <- matrix(1:6, nrow = 2, dimnames = list(c("B", "C"), paste0("T", 1:3))) out <- gexp_download_normalize_ids_for_overlap( micro_expr_list = list(M = m), rna_counts_list = list(R = r) ) names(out)
Download and parse one microarray GSE
gexp_download_one_microarray_gse(gse_id, micro_dir)gexp_download_one_microarray_gse(gse_id, micro_dir)
gse_id |
GEO series ID. |
micro_dir |
Directory for supplementary files. |
List with status, log text, reason, expression, metadata, eset, platform_id, and cel_paths.
if (interactive()) { out <- gexp_download_one_microarray_gse("GSE10072", tempdir()) out$ok }if (interactive()) { out <- gexp_download_one_microarray_gse("GSE10072", tempdir()) out$ok }
Download and parse one RNA-seq GSE
gexp_download_one_rnaseq_gse(gse_id, rna_dir)gexp_download_one_rnaseq_gse(gse_id, rna_dir)
gse_id |
GEO series ID. |
rna_dir |
Directory containing |
List with status, reason, log text, count matrix, and metadata.
if (interactive()) { out <- gexp_download_one_rnaseq_gse("GSE50760", tempdir()) out$ok }if (interactive()) { out <- gexp_download_one_rnaseq_gse("GSE50760", tempdir()) out$ok }
Fetch sample metadata from GEO series matrix fallback
gexp_fetch_geo_series_matrix_metadata(gse_id)gexp_fetch_geo_series_matrix_metadata(gse_id)
gse_id |
GEO series ID. |
data.frame or NULL.
if (interactive()) { md <- gexp_fetch_geo_series_matrix_metadata("GSE10072") if (!is.null(md)) head(md) }if (interactive()) { md <- gexp_fetch_geo_series_matrix_metadata("GSE10072") if (!is.null(md)) head(md) }
Build diagnostic log text when no common genes are found
gexp_no_common_genes_diagnostic_log(all_genes_list)gexp_no_common_genes_diagnostic_log(all_genes_list)
all_genes_list |
Named list of row IDs per dataset. |
Character string for log appending.
txt <- gexp_no_common_genes_diagnostic_log( list(D1 = c("1007_s_at", "1053_at"), D2 = c("ENSG000001", "ENSG000002")) ) nchar(txt) > 0txt <- gexp_no_common_genes_diagnostic_log( list(D1 = c("1007_s_at", "1053_at"), D2 = c("ENSG000001", "ENSG000002")) ) nchar(txt) > 0
This is a non-Shiny helper version of the Step 3 logic:
per-dataset normalization (microarray + RNA-seq),
intersection of gene sets (common genes),
global quantile normalization of the combined matrix,
optional extraction of RNA-seq raw counts for count-based DE.
gexp_normalize_and_intersect( micro_expr_list, rna_counts_list, micro_norm_method = "quantile", rnaseq_norm_method = "TMM", micro_cel_paths = NULL, platform_per_gse = NULL, micro_eset_list = NULL, de_method = "limma", apply_global_quantile = TRUE )gexp_normalize_and_intersect( micro_expr_list, rna_counts_list, micro_norm_method = "quantile", rnaseq_norm_method = "TMM", micro_cel_paths = NULL, platform_per_gse = NULL, micro_eset_list = NULL, de_method = "limma", apply_global_quantile = TRUE )
micro_expr_list |
named list of microarray expression matrices. |
rna_counts_list |
named list of RNA-seq count matrices. |
micro_norm_method |
"quantile" or "rma" (RMA requires CEL paths). |
rnaseq_norm_method |
"TMM" or "log2cpm_only". |
micro_cel_paths |
optional named list of CEL paths per GSE (for RMA). |
platform_per_gse |
optional named vector giving platform IDs per GSE. |
micro_eset_list |
optional named list of ExpressionSet objects per GSE (for RMA ID mapping). |
de_method |
differential expression method (used to decide whether to save raw counts for DESeq2/edgeR/limma-voom); one of "limma", "limma_voom", "deseq2", "edger". |
apply_global_quantile |
logical; if TRUE, apply limma quantile normalization across all samples. |
A list with elements:
combined_expr |
globally quantile-normalized matrix (genes x samples) |
combined_expr_before_global |
matrix before global quantile |
all_expr_norm_list |
normalized per-dataset matrices (common genes only) |
common_genes |
character vector of common genes |
normalization_stats |
list of per-dataset normalization info |
normalization_summary_table |
data.frame summarizing gene counts |
raw_counts_for_deseq2 |
integer matrix of RNA-seq counts (optional) |
raw_counts_metadata |
data.frame with sample metadata for raw counts (optional) |
unified_metadata |
data.frame with SampleID, Platform, Dataset, Condition=NA |
log_text |
character string with a human-readable log |
out <- withr::with_seed(1, { m1 <- matrix(abs(rnorm(120)), nrow = 20, ncol = 6) m2 <- matrix(abs(rnorm(120)), nrow = 20, ncol = 6) rownames(m1) <- rownames(m2) <- paste0("Gene", seq_len(20)) colnames(m1) <- paste0("D1_S", seq_len(6)) colnames(m2) <- paste0("D2_S", seq_len(6)) gexp_normalize_and_intersect( micro_expr_list = list(D1 = m1, D2 = m2), rna_counts_list = list(), de_method = "limma" ) }) dim(out$combined_expr)out <- withr::with_seed(1, { m1 <- matrix(abs(rnorm(120)), nrow = 20, ncol = 6) m2 <- matrix(abs(rnorm(120)), nrow = 20, ncol = 6) rownames(m1) <- rownames(m2) <- paste0("Gene", seq_len(20)) colnames(m1) <- paste0("D1_S", seq_len(6)) colnames(m2) <- paste0("D2_S", seq_len(6)) gexp_normalize_and_intersect( micro_expr_list = list(D1 = m1, D2 = m2), rna_counts_list = list(), de_method = "limma" ) }) dim(out$combined_expr)
Parse GSE IDs from Shiny text inputs
gexp_parse_gse_inputs( analysis_type, rnaseq_gses = "", microarray_gses = "", dataset_mode = "multi" )gexp_parse_gse_inputs( analysis_type, rnaseq_gses = "", microarray_gses = "", dataset_mode = "multi" )
analysis_type |
One of "rnaseq", "microarray", or "merged". |
rnaseq_gses |
Text field for RNA-seq IDs. |
microarray_gses |
Text field for microarray IDs. |
dataset_mode |
"single" or "multi". |
List with rnaseq_ids, micro_ids, dataset_mode, and messages.
x <- gexp_parse_gse_inputs( analysis_type = "merged", rnaseq_gses = "GSE1, GSE2", microarray_gses = "GSE3", dataset_mode = "single" ) x$rnaseq_idsx <- gexp_parse_gse_inputs( analysis_type = "merged", rnaseq_gses = "GSE1, GSE2", microarray_gses = "GSE3", dataset_mode = "single" ) x$rnaseq_ids
Prepare clean download directories for current run
gexp_prepare_download_dirs( base_dir = getwd(), has_micro = FALSE, has_rna = FALSE )gexp_prepare_download_dirs( base_dir = getwd(), has_micro = FALSE, has_rna = FALSE )
base_dir |
Base working directory. |
has_micro |
Logical; whether microarray IDs exist. |
has_rna |
Logical; whether RNA-seq IDs exist. |
Character vector log lines describing cleanup.
td <- tempdir() gexp_prepare_download_dirs(td, has_micro = TRUE, has_rna = TRUE)td <- tempdir() gexp_prepare_download_dirs(td, has_micro = TRUE, has_rna = TRUE)
Used by QC outlier plots before normalization builds unified metadata.
gexp_qc_build_sample_dataset_map(micro_expr_list, rna_counts_list)gexp_qc_build_sample_dataset_map(micro_expr_list, rna_counts_list)
micro_expr_list |
Named list of microarray matrices. |
rna_counts_list |
Named list of RNA-seq matrices. |
Named character vector: sample ID -> GSE accession.
m <- matrix(1:4, nrow = 2, ncol = 2, dimnames = list(c("A", "B"), c("S1", "S2"))) r <- matrix(1:4, nrow = 2, ncol = 2, dimnames = list(c("A", "B"), c("S3", "S4"))) gexp_qc_build_sample_dataset_map(list(GSE1 = m), list(GSE2 = r))m <- matrix(1:4, nrow = 2, ncol = 2, dimnames = list(c("A", "B"), c("S1", "S2"))) r <- matrix(1:4, nrow = 2, ncol = 2, dimnames = list(c("A", "B"), c("S3", "S4"))) gexp_qc_build_sample_dataset_map(list(GSE1 = m), list(GSE2 = r))
Uses two methods on the top variable genes:
PCA Mahalanobis distance (97.5% chi-square cutoff),
Sample connectivity in signed network (power = 6; mean - 2*SD threshold).
gexp_qc_detect_outliers(expr, top_n = 5000L)gexp_qc_detect_outliers(expr, top_n = 5000L)
expr |
Numeric matrix with genes in rows and samples in columns. |
top_n |
Integer number of top variable genes to use (default 5000). |
List with outlier detection results.
expr <- matrix(rnorm(400), nrow = 40, ncol = 10) rownames(expr) <- paste0("Gene", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) out <- gexp_qc_detect_outliers(expr, top_n = 20) length(out$all_outliers)expr <- matrix(rnorm(400), nrow = 40, ncol = 10) rownames(expr) <- paste0("Gene", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) out <- gexp_qc_detect_outliers(expr, top_n = 20) length(out$all_outliers)
Exclude selected samples from download/QC state lists
gexp_qc_exclude_samples( combined_expr_raw, micro_expr_list, rna_counts_list, unified_metadata = NULL, samples_to_exclude )gexp_qc_exclude_samples( combined_expr_raw, micro_expr_list, rna_counts_list, unified_metadata = NULL, samples_to_exclude )
combined_expr_raw |
Matrix genes x samples. |
micro_expr_list |
Named list of microarray matrices. |
rna_counts_list |
Named list of RNA-seq matrices. |
unified_metadata |
Optional metadata data.frame with SampleID column. |
samples_to_exclude |
Character vector of sample IDs. |
List containing updated matrices/lists/metadata.
expr <- matrix(rnorm(300), nrow = 30, ncol = 10) rownames(expr) <- paste0("Gene", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) meta <- data.frame(SampleID = colnames(expr), stringsAsFactors = FALSE) res <- gexp_qc_exclude_samples( combined_expr_raw = expr, micro_expr_list = list(D1 = expr[, 1:5, drop = FALSE]), rna_counts_list = list(D2 = expr[, 6:10, drop = FALSE]), unified_metadata = meta, samples_to_exclude = c("S1", "S10") ) ncol(res$combined_expr_raw)expr <- matrix(rnorm(300), nrow = 30, ncol = 10) rownames(expr) <- paste0("Gene", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) meta <- data.frame(SampleID = colnames(expr), stringsAsFactors = FALSE) res <- gexp_qc_exclude_samples( combined_expr_raw = expr, micro_expr_list = list(D1 = expr[, 1:5, drop = FALSE]), rna_counts_list = list(D2 = expr[, 6:10, drop = FALSE]), unified_metadata = meta, samples_to_exclude = c("S1", "S10") ) ncol(res$combined_expr_raw)
Build gene-overlap summary table for QC UI
gexp_qc_gene_overlap_summary(all_genes_list, common_genes)gexp_qc_gene_overlap_summary(all_genes_list, common_genes)
all_genes_list |
Named list of gene vectors by dataset. |
common_genes |
Character vector of common genes. |
Data.frame with Dataset, Total_Genes, Pct_in_Common.
all_genes <- list( D1 = c("A", "B", "C", "D"), D2 = c("B", "C", "E") ) gexp_qc_gene_overlap_summary(all_genes, common_genes = c("B", "C"))all_genes <- list( D1 = c("A", "B", "C", "D"), D2 = c("B", "C", "E") ) gexp_qc_gene_overlap_summary(all_genes, common_genes = c("B", "C"))
Prepare QC boxplot data from combined expression
gexp_qc_prepare_boxplot_data( combined_expr_raw, micro_expr_list, rna_counts_list, max_points = 500000L )gexp_qc_prepare_boxplot_data( combined_expr_raw, micro_expr_list, rna_counts_list, max_points = 500000L )
combined_expr_raw |
Matrix genes x samples. |
micro_expr_list |
Named list of microarray matrices. |
rna_counts_list |
Named list of RNA-seq matrices. |
max_points |
Maximum rows to keep for plotting. |
data.frame with Expression, Sample, Platform.
expr <- matrix(rnorm(120), nrow = 12, ncol = 10) rownames(expr) <- paste0("Gene", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) df <- gexp_qc_prepare_boxplot_data( combined_expr_raw = expr, micro_expr_list = list(D1 = expr[, 1:5, drop = FALSE]), rna_counts_list = list(D2 = expr[, 6:10, drop = FALSE]), max_points = 1000 ) head(df)expr <- matrix(rnorm(120), nrow = 12, ncol = 10) rownames(expr) <- paste0("Gene", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) df <- gexp_qc_prepare_boxplot_data( combined_expr_raw = expr, micro_expr_list = list(D1 = expr[, 1:5, drop = FALSE]), rna_counts_list = list(D2 = expr[, 6:10, drop = FALSE]), max_points = 1000 ) head(df)
Prepare density curves for QC density plot
gexp_qc_prepare_density_data(combined_expr_raw, max_samples = 50L)gexp_qc_prepare_density_data(combined_expr_raw, max_samples = 50L)
combined_expr_raw |
Matrix genes x samples. |
max_samples |
Maximum number of sample density lines to include. |
List with first density, additional densities, and colors.
expr <- matrix(rnorm(200), nrow = 20, ncol = 10) d <- gexp_qc_prepare_density_data(expr, max_samples = 5) length(d$others)expr <- matrix(rnorm(200), nrow = 20, ncol = 10) d <- gexp_qc_prepare_density_data(expr, max_samples = 5) length(d$others)
Prepare UpSet matrix data from per-dataset genes
gexp_qc_prepare_upset_data(all_genes_list)gexp_qc_prepare_upset_data(all_genes_list)
all_genes_list |
Named list of gene vectors by dataset. |
List with ok, upset_df, gene_lists, max_set_size, and message.
sets <- list( D1 = c("A", "B", "C"), D2 = c("B", "C", "D") ) out <- gexp_qc_prepare_upset_data(sets) names(out)sets <- list( D1 = c("A", "B", "C"), D2 = c("B", "C", "D") ) out <- gexp_qc_prepare_upset_data(sets) names(out)
Prepare cleaned gene sets for Venn plotting
gexp_qc_prepare_venn_sets(all_genes_list, max_sets = 5L)gexp_qc_prepare_venn_sets(all_genes_list, max_sets = 5L)
all_genes_list |
Named list of gene vectors by dataset. |
max_sets |
Maximum number of sets to keep for Venn plotting. |
List with ok, sets, and message.
sets <- list( D1 = c("A", "B", "C"), D2 = c("B", "C", "D"), D3 = c("A", "D") ) out <- gexp_qc_prepare_venn_sets(sets) out$oksets <- list( D1 = c("A", "B", "C"), D2 = c("B", "C", "D"), D3 = c("A", "D") ) out <- gexp_qc_prepare_venn_sets(sets) out$ok
Rebuild per-dataset gene lists from expression/count lists
gexp_rebuild_all_genes_list(micro_expr_list, rna_counts_list)gexp_rebuild_all_genes_list(micro_expr_list, rna_counts_list)
micro_expr_list |
Named list of microarray matrices. |
rna_counts_list |
Named list of RNA-seq matrices. |
Named list of gene vectors.
m <- matrix(1:6, nrow = 2, dimnames = list(c("A", "B"), paste0("S", 1:3))) r <- matrix(1:6, nrow = 2, dimnames = list(c("B", "C"), paste0("T", 1:3))) gexp_rebuild_all_genes_list(list(M = m), list(R = r))m <- matrix(1:6, nrow = 2, dimnames = list(c("A", "B"), paste0("S", 1:3))) r <- matrix(1:6, nrow = 2, dimnames = list(c("B", "C"), paste0("T", 1:3))) gexp_rebuild_all_genes_list(list(M = m), list(R = r))
Run differential expression analysis
gexp_run_de( expr, metadata, method = c("limma", "limma_voom", "deseq2", "edger"), logfc_cutoff = 0.5, padj_cutoff = 0.05 )gexp_run_de( expr, metadata, method = c("limma", "limma_voom", "deseq2", "edger"), logfc_cutoff = 0.5, padj_cutoff = 0.05 )
expr |
Matrix of (batch-corrected, normalized) expression values with genes in rows and samples in columns. |
metadata |
Data.frame with at least a |
method |
Currently only |
logfc_cutoff |
Numeric log2 fold-change cutoff. |
padj_cutoff |
Numeric adjusted P-value cutoff. |
list with de_results, sig_genes, filter_note, sample_info, formula_desc
expr <- matrix(rnorm(200), nrow = 20) rownames(expr) <- paste0("G", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) meta <- data.frame( Condition = rep(c("Normal", "Disease"), each = 5), row.names = colnames(expr), stringsAsFactors = FALSE ) gexp_run_de(expr, meta)expr <- matrix(rnorm(200), nrow = 20) rownames(expr) <- paste0("G", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) meta <- data.frame( Condition = rep(c("Normal", "Disease"), each = 5), row.names = colnames(expr), stringsAsFactors = FALSE ) gexp_run_de(expr, meta)
This helper mirrors the "Prepare WGCNA Data" step:
uses batch-corrected expression (or combined expression if needed),
drops samples/genes with too many missing values,
optionally filters to top variable genes,
enforces a minimum fraction of non-missing samples per gene,
returns a WGCNA-ready datExpr matrix (samples x genes) and
companion sample info and gene-variance table.
gexp_wgcna_prepare( expr, metadata, gene_mode = c("top_variable", "all_common"), top_genes = 5000L, min_samples_frac = 0.5 )gexp_wgcna_prepare( expr, metadata, gene_mode = c("top_variable", "all_common"), top_genes = 5000L, min_samples_frac = 0.5 )
expr |
Matrix of expression values (genes x samples), typically batch-corrected. |
metadata |
Data.frame with sample metadata; should contain
either rownames matching |
gene_mode |
"all_common" or "top_variable" (default). |
top_genes |
If |
min_samples_frac |
Minimum fraction of samples with non-missing expression required for a gene to be kept (default 0.5). |
A list with elements:
datExpr |
numeric matrix (samples x genes) for WGCNA |
sample_info |
data.frame with sample metadata aligned to datExpr |
gene_variance_table |
data.frame with gene variance and rank |
expr <- matrix(rnorm(600), nrow = 60) rownames(expr) <- paste0("Gene", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) metadata <- data.frame( SampleID = colnames(expr), Condition = rep(c("Normal", "Disease"), each = 5), Dataset = rep(c("D1", "D2"), each = 5), stringsAsFactors = FALSE ) prep <- gexp_wgcna_prepare(expr, metadata, gene_mode = "top_variable", top_genes = 50) dim(prep$datExpr)expr <- matrix(rnorm(600), nrow = 60) rownames(expr) <- paste0("Gene", seq_len(nrow(expr))) colnames(expr) <- paste0("S", seq_len(ncol(expr))) metadata <- data.frame( SampleID = colnames(expr), Condition = rep(c("Normal", "Disease"), each = 5), Dataset = rep(c("D1", "D2"), each = 5), stringsAsFactors = FALSE ) prep <- gexp_wgcna_prepare(expr, metadata, gene_mode = "top_variable", top_genes = 50) dim(prep$datExpr)
Build reproducibility report text for export
gexpipe_analysis_report_text(params = list(), include_session = TRUE)gexpipe_analysis_report_text(params = list(), include_session = TRUE)
params |
Named list of scalar analysis parameters (character or numeric). |
include_session |
Include |
Character vector of report lines.
gexpipe_analysis_report_text(list(method = "limma"), include_session = FALSE)gexpipe_analysis_report_text(list(method = "limma"), include_session = FALSE)
Summarise Dataset x Condition confounding for batch/DE guidance
gexpipe_batch_confounding_summary(metadata)gexpipe_batch_confounding_summary(metadata)
metadata |
data.frame with Dataset and Condition columns. |
list with confounded (logical), table (matrix), message (character)
meta <- data.frame( Dataset = rep(c("GSE1", "GSE2"), each = 3), Condition = rep(c("Normal", "Disease"), times = 3) ) gexpipe_batch_confounding_summary(meta)meta <- data.frame( Dataset = rep(c("GSE1", "GSE2"), each = 3), Condition = rep(c("Normal", "Disease"), times = 3) ) gexpipe_batch_confounding_summary(meta)
Summarise how Platform should enter batch/DE models
gexpipe_batch_covariate_info(metadata)gexpipe_batch_covariate_info(metadata)
metadata |
sample metadata data.frame. |
list with mixed_platforms, platform_dataset_confounded, include_platform_covariate
meta <- data.frame( Dataset = rep(c("GSE1", "GSE2"), each = 2), Platform = rep(c("Microarray", "RNAseq"), each = 2) ) gexpipe_batch_covariate_info(meta)meta <- data.frame( Dataset = rep(c("GSE1", "GSE2"), each = 2), Platform = rep(c("Microarray", "RNAseq"), each = 2) ) gexpipe_batch_covariate_info(meta)
Build ComBat / removeBatchEffect model matrix (biology to preserve)
gexpipe_build_batch_mod(metadata)gexpipe_build_batch_mod(metadata)
metadata |
sample metadata data.frame. |
model matrix
meta <- data.frame( Condition = rep(c("Normal", "Disease"), each = 3), row.names = paste0("S", 1:6), stringsAsFactors = FALSE ) gexpipe_build_batch_mod(meta)meta <- data.frame( Condition = rep(c("Normal", "Disease"), each = 3), row.names = paste0("S", 1:6), stringsAsFactors = FALSE ) gexpipe_build_batch_mod(meta)
Build a model matrix for DE (limma / edgeR / voom)
gexpipe_build_de_design(metadata)gexpipe_build_de_design(metadata)
metadata |
data.frame with Dataset, Platform, Condition columns. |
list with design, coef_condition, formula_desc, info
meta <- data.frame( Dataset = rep(c("GSE1", "GSE2"), each = 3), Condition = rep(c("Normal", "Disease"), times = 3), row.names = paste0("S", 1:6), stringsAsFactors = FALSE ) gexpipe_build_de_design(meta)meta <- data.frame( Dataset = rep(c("GSE1", "GSE2"), each = 3), Condition = rep(c("Normal", "Disease"), times = 3), row.names = paste0("S", 1:6), stringsAsFactors = FALSE ) gexpipe_build_de_design(meta)
Summarise samples used in a DE run (transparency for mixed-platform runs)
gexpipe_de_sample_info(meta_used, total_meta = NULL, method = "limma")gexpipe_de_sample_info(meta_used, total_meta = NULL, method = "limma")
meta_used |
Metadata rows actually used in the DE fit. |
total_meta |
Full unified metadata before subsetting (optional). |
method |
DE method name. |
list with human-readable fields for the Shiny UI.
meta <- data.frame( Condition = rep(c("Normal", "Disease"), each = 3), Platform = "RNAseq", row.names = paste0("S", 1:6), stringsAsFactors = FALSE ) gexpipe_de_sample_info(meta)meta <- data.frame( Condition = rep(c("Normal", "Disease"), each = 3), Platform = "RNAseq", row.names = paste0("S", 1:6), stringsAsFactors = FALSE ) gexpipe_de_sample_info(meta)
DESeq2 design formula for count-based DE
gexpipe_deseq2_design(metadata)gexpipe_deseq2_design(metadata)
metadata |
sample metadata data.frame. |
list with formula (formula object) and formula_desc (character)
meta <- data.frame( Condition = rep(c("Normal", "Disease"), each = 3), row.names = paste0("S", 1:6), stringsAsFactors = FALSE ) gexpipe_deseq2_design(meta)meta <- data.frame( Condition = rep(c("Normal", "Disease"), each = 3), row.names = paste0("S", 1:6), stringsAsFactors = FALSE ) gexpipe_deseq2_design(meta)
Detect microarray + RNA-seq in the same analysis
gexpipe_has_mixed_platforms(metadata)gexpipe_has_mixed_platforms(metadata)
metadata |
data.frame with optional |
logical
meta <- data.frame(Platform = c("Microarray", "RNAseq")) gexpipe_has_mixed_platforms(meta)meta <- data.frame(Platform = c("Microarray", "RNAseq")) gexpipe_has_mixed_platforms(meta)
Removes lowly expressed genes using a design-aware filter so filtering is not tied to differential expression statistics (avoids FDR bias from variance-percentile pre-filtering).
gexpipe_independent_filter(expr, design = NULL, group = NULL)gexpipe_independent_filter(expr, design = NULL, group = NULL)
expr |
Numeric matrix (genes x samples) or integer counts. |
design |
Model matrix for the DE analysis. |
group |
Optional factor when design is NULL (single-factor designs). |
list with expr (filtered), keep (logical vector), n_before, n_after, note
expr <- matrix(stats::rpois(5000, lambda = 50), nrow = 500, ncol = 10) design <- stats::model.matrix(~ factor(rep(c("A", "B"), each = 5))) gexpipe_independent_filter(expr, design = design)expr <- matrix(stats::rpois(5000, lambda = 50), nrow = 500, ncol = 10) design <- stats::model.matrix(~ factor(rep(c("A", "B"), each = 5))) gexpipe_independent_filter(expr, design = design)
Polar PCA coordinates for batch/platform diagnostic plots
gexpipe_pca_polar_df(expr, metadata, color_by = "Dataset")gexpipe_pca_polar_df(expr, metadata, color_by = "Dataset")
expr |
genes x samples matrix. |
metadata |
sample metadata aligned to expr columns. |
color_by |
column name in metadata to colour points. |
data.frame with theta, r, and colour column.
expr <- matrix(rnorm(120), 20, 6, dimnames = list(paste0("G", 1:20), paste0("S", 1:6))) meta <- data.frame(Dataset = rep(c("A", "B"), each = 3), row.names = colnames(expr)) gexpipe_pca_polar_df(expr, meta)expr <- matrix(rnorm(120), 20, 6, dimnames = list(paste0("G", 1:20), paste0("S", 1:6))) meta <- data.frame(Dataset = rep(c("A", "B"), each = 3), row.names = colnames(expr)) gexpipe_pca_polar_df(expr, meta)
Returns TRUE when Platform is nested within Dataset (each GSE has one technology)
or when a tentative ~ Dataset + Platform (+ Condition) design is rank-deficient.
gexpipe_platform_dataset_confounded(metadata)gexpipe_platform_dataset_confounded(metadata)
metadata |
data.frame with |
logical
meta <- data.frame( Dataset = c("GSE1", "GSE1", "GSE2", "GSE2"), Platform = c("Microarray", "Microarray", "RNAseq", "RNAseq") ) gexpipe_platform_dataset_confounded(meta)meta <- data.frame( Dataset = c("GSE1", "GSE1", "GSE2", "GSE2"), Platform = c("Microarray", "Microarray", "RNAseq", "RNAseq") ) gexpipe_platform_dataset_confounded(meta)
Aligns metadata to expression columns, runs PCA on samples, and estimates
the mean fraction of variance in the top PCs explained by Dataset, Platform,
and Condition. Residual is 1 - sum(factor fractions) (approximate).
gexpipe_pvca_df(expr, metadata, max_samples = 100L, max_pcs = 10L)gexpipe_pvca_df(expr, metadata, max_samples = 100L, max_pcs = 10L)
expr |
Numeric matrix, genes x samples. |
metadata |
Sample metadata with |
max_samples |
Subsample at most this many columns for speed (default 100). |
max_pcs |
Use at most this many principal components (default 10). |
A list with ok (logical), data (data.frame or NULL),
and message (character, empty on success).
expr <- matrix(rnorm(120), 20, 6, dimnames = list(paste0("G", 1:20), paste0("S", 1:6))) meta <- data.frame( Dataset = rep(c("GSE1", "GSE2"), each = 3), Condition = rep(c("Normal", "Disease"), times = 3), row.names = colnames(expr), stringsAsFactors = FALSE ) gexpipe_pvca_df(expr, meta)expr <- matrix(rnorm(120), 20, 6, dimnames = list(paste0("G", 1:20), paste0("S", 1:6))) meta <- data.frame( Dataset = rep(c("GSE1", "GSE2"), each = 3), Condition = rep(c("Normal", "Disease"), times = 3), row.names = colnames(expr), stringsAsFactors = FALSE ) gexpipe_pvca_df(expr, meta)
Detects your R version and verifies (or optionally installs) required packages.
When GExPipe is installed from Bioconductor, dependencies are installed at
package install time; gexpipe_setup() only checks availability unless
options(gexpipe.auto_install = TRUE) is set.
gexpipe_setup( update = TRUE, optional = TRUE, launch = FALSE, port = 3838L, ... )gexpipe_setup( update = TRUE, optional = TRUE, launch = FALSE, port = 3838L, ... )
update |
Logical. If |
optional |
Logical. Reserved for future optional feature packages.
Currently all runtime dependencies are in |
launch |
Logical. If |
port |
Integer. Port for the Shiny app when |
... |
Additional arguments passed to |
Invisibly returns a named logical vector indicating which packages were successfully installed/available.
# Check and install missing packages only (no updates, no launch) if (interactive()) { gexpipe_setup(update = FALSE, optional = FALSE, launch = FALSE) }# Check and install missing packages only (no updates, no launch) if (interactive()) { gexpipe_setup(update = FALSE, optional = FALSE, launch = FALSE) }
For a two-group design, WGCNA may add a combined "X vs Y" contrast column that duplicates one group indicator. This helper removes that column before plotting.
gexpipe_wgcna_heatmap_cor(cor_mat, combined)gexpipe_wgcna_heatmap_cor(cor_mat, combined)
cor_mat |
Numeric matrix of module-trait correlations. |
combined |
Name of the combined contrast column to drop, or NULL. |
The correlation matrix with the combined column removed when appropriate.
cor_mat <- matrix(runif(6), 2, 3, dimnames = list(c("ME1", "ME2"), c("A", "B", "A vs B"))) gexpipe_wgcna_heatmap_cor(cor_mat, "A vs B")cor_mat <- matrix(runif(6), 2, 3, dimnames = list(c("ME1", "ME2"), c("A", "B", "A vs B"))) gexpipe_wgcna_heatmap_cor(cor_mat, "A vs B")
Launches the GExPipe Shiny app for multi-omics RNA analysis (bulk RNA-seq, microarray, GEO download, QC, normalization, differential expression, WGCNA, pathway enrichment, PPI, machine learning, and more).
runGExPipe( launch.browser = TRUE, port = getOption("shiny.port", 3838), host = getOption("shiny.host", "127.0.0.1") )runGExPipe( launch.browser = TRUE, port = getOption("shiny.port", 3838), host = getOption("shiny.host", "127.0.0.1") )
launch.browser |
If TRUE, open the app in the default browser (default). Set to FALSE in Google Colab or headless servers (no local browser). |
port |
TCP port for Shiny. Use a positive port (e.g. |
host |
The host to bind. Use "0.0.0.0" in Google Colab so port forwarding works. |
A Shiny app object. Users should run it with shiny::runApp(), which
starts the server and blocks the R session until the app is stopped
(e.g. RStudio Stop button).
When GExPipe is installed from Bioconductor (or any normal R library),
dependencies must be installed at package install time via
BiocManager::install("GExPipe", dependencies = TRUE). runGExPipe()
then verifies imports and opens the app without downloading packages.
For the GitHub / first-run workflow, set
options(gexpipe.auto_install = TRUE) before runGExPipe() to enable
background dependency installation (10-30 minutes on a fresh machine).
The welcome screen loads first; the full 15-tab dashboard is built only
after the user clicks Go to Analysis, so the initial browser response is
fast even on slow networks. Prefer GExPipe::runGExPipe() from an
installed package rather than opening inst/shinyapp/ in RStudio
directly (that path runs global.R, which duplicates the install logic).
Optional tuning before runGExPipe():
options(gexpipe.wgcna_threads = 1L) - fewer WGCNA threads (less parallel setup noise).
options(gexpipe.wgcna_threads = 0L) or FALSE - skip WGCNA::enableWGCNAThreads() at app start.
options(shiny.testmode = TRUE) with options(gexpipe.minimal_attach_in_testmode = TRUE) (default
when unset) attaches only the Shiny stack first, then the rest after the first flush, so
automated tests can connect quickly. Set gexpipe.minimal_attach_in_testmode = FALSE for a
full attach on the first tick (e.g. deep shinytest2 scenarios).
Install with full dependencies so STRINGdb support packages resolve:
BiocManager::install("GExPipe", dependencies = TRUE). STRINGdb is installed as a dependency.
The first PPI run may download large STRING files (requires network). If initialization fails,
try options(gexpipe.stringdb_try_versions = c("11.5", "11", "12")) or update STRINGdb.
# Non-interactive (R CMD check / example()): build an app object only. # Dependency auto-install is skipped when interactive() is FALSE, so this # runs quickly without touching the network. app <- runGExPipe(launch.browser = FALSE, port = 0L) stopifnot(inherits(app, "shiny.appobj")) # Interactive: two-step launch. runGExPipe() builds the app object # (installing any missing packages on first run); shiny::runApp() starts it. if (interactive()) { app <- GExPipe::runGExPipe() # Step 1: build the app object shiny::runApp(app, port = 3838L) # Step 2: start the server }# Non-interactive (R CMD check / example()): build an app object only. # Dependency auto-install is skipped when interactive() is FALSE, so this # runs quickly without touching the network. app <- runGExPipe(launch.browser = FALSE, port = 0L) stopifnot(inherits(app, "shiny.appobj")) # Interactive: two-step launch. runGExPipe() builds the app object # (installing any missing packages on first run); shiny::runApp() starts it. if (interactive()) { app <- GExPipe::runGExPipe() # Step 1: build the app object shiny::runApp(app, port = 3838L) # Step 2: start the server }