[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-aws-labs-multi-omics-pipeline":3,"mdc-emk3v9-key":49,"related-repo-aws-labs-multi-omics-pipeline":3379,"related-org-aws-labs-multi-omics-pipeline":3479},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":26,"repoUrl":27,"updatedAt":28,"license":29,"forks":30,"topics":31,"repo":44,"sourceUrl":47,"mdContent":48},"multi-omics-pipeline","process and integrate multi-omics data","Pipeline skill for multi-omics data processing and integration. Use when the user asks to map gene IDs between HGNC Ensembl and UniProt, convert between omic data formats, run batch correction with ComBat or ComBat-seq, perform GSEA or over-representation analysis on multi-omic results, run consensus clustering on integrated data, execute MOFA2 in R or mofapy2 in Python, build a multi-omics ETL pipeline, harmonize feature identifiers across omics layers, or run clusterProfiler enrichment. Triggers include \"map Ensembl to HGNC\", \"ID mapping omics\", \"ComBat code\", \"run MOFA2\", \"mofapy2\", \"GSEA Python\", \"fgsea R\", \"consensus clustering\", \"multi-omics pipeline\", \"gseapy\", \"biomaRt\", \"clusterProfiler\", \"mixOmics DIABLO\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"aws-labs","AWS Labs","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Faws-labs.png","awslabs",[13,17,20,23],{"name":14,"slug":15,"type":16},"Data Engineering","data-engineering","tag",{"name":18,"slug":19,"type":16},"Data Pipeline","data-pipeline",{"name":21,"slug":22,"type":16},"Life Sciences","life-sciences",{"name":24,"slug":25,"type":16},"Bioinformatics","bioinformatics",4,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fhcls-agent-skills","2026-07-12T08:38:00.363983",null,0,[32,33,34,35,36,37,38,39,40,22,41,42,43],"agent-skills","agentcore","ai-agents","amazon-quick-desktop","claims-processing","drug-discovery","genomics","healthcare-ai","kiro","medical-imaging","risk-adjustment","strands-agents",{"repoUrl":27,"stars":26,"forks":30,"topics":45,"description":46},[32,33,34,35,36,37,38,39,40,22,41,42,43],"Agent skills for healthcare and life sciences: genomics, imaging, claims, drug discovery, and more. Works with Amazon Quick, Kiro, Amazon AgentCore, AWS Strands SDK, Claude Code, Codex, and any Agent Skills-compatible platform.","https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fhcls-agent-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fmulti-omics-pipeline","---\nname: multi-omics-pipeline\ndescription: >\n  Pipeline skill for multi-omics data processing and integration. Use when the user asks to\n  map gene IDs between HGNC Ensembl and UniProt, convert between omic data formats, run\n  batch correction with ComBat or ComBat-seq, perform GSEA or over-representation analysis\n  on multi-omic results, run consensus clustering on integrated data, execute MOFA2 in R\n  or mofapy2 in Python, build a multi-omics ETL pipeline, harmonize feature identifiers\n  across omics layers, or run clusterProfiler enrichment. Triggers include \"map Ensembl to\n  HGNC\", \"ID mapping omics\", \"ComBat code\", \"run MOFA2\", \"mofapy2\", \"GSEA Python\",\n  \"fgsea R\", \"consensus clustering\", \"multi-omics pipeline\", \"gseapy\", \"biomaRt\",\n  \"clusterProfiler\", \"mixOmics DIABLO\".\nusage: Invoke to generate executable code for multi-omics ID mapping, batch correction, factor analysis, enrichment, and consensus clustering.\nversion: 1.0.0\nvalidated_against:\n  date: 2025-01-15\n  packages: {mofa2: \"1.12\", combat: \"0.3.4\", gseapy: \"1.1\"}\ntags: [skill, category:pipeline, multi-omics, etl, hcls]\n---\n\n# Multi-Omics Pipeline — Pipeline Skill\n\n## Overview\n\nProvide deterministic, copy-paste-ready code for multi-omics data processing tasks: ID mapping,\nbatch correction, integration via MOFA2\u002Fmofapy2, enrichment analysis, and consensus clustering.\n\n## Usage\n\n- Map gene identifiers across HGNC, Ensembl, and UniProt systems\n- Run batch correction (ComBat\u002FComBat-seq) and multi-omic factor analysis (MOFA2\u002Fmofapy2)\n- Perform GSEA enrichment and consensus clustering on integrated data\n\n## Core Concepts\n\n---\n\n\n## Response Format\n\n- Lead with the command or code the user needs — explain after\n- Structure as: confirm inputs → working code → key parameters explained → gotchas\n- One complete working example per task; do not show every alternative\n- Keep code comments minimal and functional (what, not why-it-exists)\n- Target: 50-100 lines of code with brief surrounding explanation\n\n## 1. ID Mapping\n\n### 1a. Python — HGNC Symbol ↔ Ensembl ↔ UniProt\n\n```python\nimport pandas as pd\nimport mygene\n\nmg = mygene.MyGeneInfo()\n\n# Input: list of HGNC symbols\ngenes = [\"TP53\", \"BRCA1\", \"EGFR\", \"KRAS\"]\n\n# Query multiple ID types at once\nresult = mg.querymany(\n    genes,\n    scopes=\"symbol\",\n    fields=\"ensembl.gene,uniprot.Swiss-Prot\",\n    species=\"human\",\n    returnall=True,\n)\n\ndf = pd.DataFrame(result[\"out\"])\n# Handle many-to-many: explode nested Ensembl IDs\ndf_ensembl = df.explode(\"ensembl\")\ndf_ensembl[\"ensembl_id\"] = df_ensembl[\"ensembl\"].apply(\n    lambda x: x[\"gene\"] if isinstance(x, dict) else None\n)\nprint(df_ensembl[[\"query\", \"ensembl_id\"]].dropna())\n```\n\n### 1b. R — biomaRt\n\n```r\nlibrary(biomaRt)\n\nensembl \u003C- useEnsembl(biomart = \"genes\", dataset = \"hsapiens_gene_ensembl\")\n\n# Map HGNC symbols to Ensembl gene IDs and UniProt accessions\nmapping \u003C- getBM(\n  attributes = c(\"hgnc_symbol\", \"ensembl_gene_id\", \"uniprotswissprot\"),\n  filters = \"hgnc_symbol\",\n  values = c(\"TP53\", \"BRCA1\", \"EGFR\", \"KRAS\"),\n  mart = ensembl\n)\n\n# Remove rows with empty UniProt\nmapping \u003C- mapping[mapping$uniprotswissprot != \"\", ]\nprint(mapping)\n```\n\n### ID Mapping Parameter Table\n\n| Parameter | Python (mygene) | R (biomaRt) |\n|---|---|---|\n| Input ID type | `scopes=\"symbol\"` | `filters = \"hgnc_symbol\"` |\n| Output ID types | `fields=\"ensembl.gene,uniprot.Swiss-Prot\"` | `attributes = c(\"ensembl_gene_id\", \"uniprotswissprot\")` |\n| Species filter | `species=\"human\"` | `dataset = \"hsapiens_gene_ensembl\"` |\n| Many-to-many handling | Explode nested lists | Multiple rows returned automatically |\n\n---\n\n## 2. Batch Correction\n\n### 2a. Python — ComBat (pycombat)\n\n```python\nfrom combat.pycombat import pycombat\nimport pandas as pd\nimport numpy as np\n\n# expression_df: genes (rows) x samples (columns), log-transformed\n# batch: list of batch labels, same order as columns\n# covariates: DataFrame with biological covariates to protect\n\nexpression_df = pd.read_csv(\"expression_matrix.csv\", index_col=0)\nbatch = [1, 1, 1, 2, 2, 2, 3, 3, 3]  # batch labels per sample\n\n# Protect biological covariate (e.g., disease status)\ncovar_df = pd.DataFrame({\"disease\": [0, 0, 1, 0, 1, 1, 0, 1, 1]})\n\ncorrected = pycombat(\n    expression_df,\n    batch,\n    mod=covar_df,       # biological covariates to protect\n    par_prior=True,     # parametric adjustment (default)\n)\n```\n\n### 2b. R — ComBat \u002F ComBat-seq\n\n```r\nlibrary(sva)\n\n# For continuous data (log-transformed expression, protein intensity)\n# expr_mat: genes x samples matrix\n# batch: vector of batch labels\n# mod: model matrix with biological covariates to protect\n\nmod \u003C- model.matrix(~ disease_status, data = sample_info)\n\ncorrected \u003C- ComBat(\n  dat = expr_mat,\n  batch = sample_info$batch,\n  mod = mod,\n  par.prior = TRUE  # parametric\n)\n\n# For count data (RNA-seq raw counts) — use ComBat-seq\ncorrected_counts \u003C- ComBat_seq(\n  counts = count_mat,\n  batch = sample_info$batch,\n  group = sample_info$disease_status  # biological variable to protect\n)\n```\n\n### Batch Correction Parameter Table\n\n| Parameter | ComBat (continuous) | ComBat-seq (counts) |\n|---|---|---|\n| Input | Log-transformed matrix | Raw count matrix (integers) |\n| Parametric prior | `par.prior = TRUE` (default) | Not applicable |\n| Biological covariate | `mod` (model matrix) | `group` (vector) |\n| Output | Corrected continuous matrix | Corrected count matrix |\n| When to use | Proteomics, methylation M-values, log-expression | RNA-seq raw counts |\n\n---\n\n## 3. MOFA2 \u002F mofapy2 Integration\n\n### 3a. R — MOFA2\n\n```r\nlibrary(MOFA2)\n\n# Prepare data: list of matrices, one per omic layer\n# Each matrix: features x samples\ndata_list \u003C- list(\n  transcriptomics = expr_mat,   # genes x samples\n  proteomics = prot_mat,        # proteins x samples\n  methylation = meth_mat        # CpG sites x samples\n)\n\n# Create MOFA object\nmofa \u003C- create_mofa(data_list)\n\n# Set data options\ndata_opts \u003C- get_default_data_options(mofa)\n\n# Set model options\nmodel_opts \u003C- get_default_model_options(mofa)\nmodel_opts$num_factors \u003C- 20  # start with 20; inactive factors pruned automatically\n\n# Set training options\ntrain_opts \u003C- get_default_training_options(mofa)\ntrain_opts$convergence_mode \u003C- \"slow\"  # more iterations for better convergence\ntrain_opts$seed \u003C- 42\n\n# Prepare and run\nmofa \u003C- prepare_mofa(\n  mofa,\n  data_options = data_opts,\n  model_options = model_opts,\n  training_options = train_opts\n)\n\nmofa \u003C- run_mofa(mofa, outfile = \"mofa_model.hdf5\")\n\n# Inspect variance explained per factor per view\nplot_variance_explained(mofa)\n\n# Extract top features for factor 1\nweights \u003C- get_weights(mofa, views = \"transcriptomics\", factors = 1, as.data.frame = TRUE)\ntop_genes \u003C- weights[order(abs(weights$value), decreasing = TRUE), ][1:50, ]\n```\n\n### 3b. Python — mofapy2\n\n```python\nfrom mofapy2.run.entry_point import entry_point\nimport numpy as np\n\n# Prepare data: list of numpy arrays [views][groups]\n# Each array: samples x features\ndata = [\n    [expr_array],   # view 0: transcriptomics, group 0\n    [prot_array],   # view 1: proteomics, group 0\n    [meth_array],   # view 2: methylation, group 0\n]\n\nent = entry_point()\nent.set_data_options(scale_groups=False, scale_views=True)\nent.set_data_matrix(data, views_names=[\"transcriptomics\", \"proteomics\", \"methylation\"])\n\nent.set_model_options(factors=20, spikeslab_weights=True, ard_factors=True)\nent.set_train_options(iter=1000, convergence_mode=\"slow\", seed=42)\n\nent.build()\nent.run()\nent.save(\"mofa_model.hdf5\")\n```\n\n### MOFA Parameter Table\n\n| Parameter | Default | Guidance |\n|---|---|---|\n| `num_factors` \u002F `factors` | 10 | Set 15–25 for exploratory analysis; inactive factors auto-pruned |\n| `convergence_mode` | `\"fast\"` | Use `\"slow\"` for final analysis; `\"fast\"` for exploration |\n| `scale_views` | `TRUE` \u002F `True` | MUST be True to equalize variance across views |\n| `spikeslab_weights` | `TRUE` \u002F `True` | Enables sparse feature selection per factor |\n| `ard_factors` | `TRUE` \u002F `True` | Automatic relevance determination; prunes inactive factors |\n| `seed` | None | ALWAYS set for reproducibility |\n\n---\n\n## 4. GSEA Enrichment\n\n### 4a. Python — gseapy\n\n```python\nimport gseapy as gp\nimport pandas as pd\n\n# ranked_genes: DataFrame with columns [\"gene\", \"rank_metric\"]\n# rank_metric can be: log2FC, -log10(p) * sign(FC), or MOFA weight\nranked_genes = pd.read_csv(\"ranked_genes.csv\")\n\n# Pre-ranked GSEA against MSigDB Hallmark gene sets\nresult = gp.prerank(\n    rnk=ranked_genes,\n    gene_sets=\"MSigDB_Hallmark_2020\",\n    min_size=15,\n    max_size=500,\n    permutation_num=1000,\n    seed=42,\n    outdir=\"gsea_results\",\n)\n\n# Filter significant results\nsig = result.res2d[result.res2d[\"FDR q-val\"] \u003C 0.05]\nprint(sig[[\"Term\", \"NES\", \"FDR q-val\"]].sort_values(\"NES\", ascending=False))\n```\n\n### 4b. R — fgsea with clusterProfiler\n\n```r\nlibrary(fgsea)\nlibrary(msigdbr)\n\n# Get Hallmark gene sets for human\nhallmark \u003C- msigdbr(species = \"Homo sapiens\", category = \"H\")\npathways \u003C- split(hallmark$gene_symbol, hallmark$gs_name)\n\n# ranked_genes: named numeric vector (names = gene symbols, values = rank metric)\nranked_genes \u003C- setNames(de_results$log2FoldChange, de_results$gene_symbol)\nranked_genes \u003C- sort(ranked_genes, decreasing = TRUE)\n\n# Run fgsea\nfgsea_res \u003C- fgsea(\n  pathways = pathways,\n  stats = ranked_genes,\n  minSize = 15,\n  maxSize = 500,\n  nPermSimple = 10000\n)\n\n# Filter and sort\nsig_pathways \u003C- fgsea_res[fgsea_res$padj \u003C 0.05, ]\nsig_pathways \u003C- sig_pathways[order(sig_pathways$NES, decreasing = TRUE), ]\nprint(sig_pathways[, c(\"pathway\", \"NES\", \"padj\")])\n```\n\n### Enrichment Parameter Table\n\n| Parameter | gseapy (Python) | fgsea (R) |\n|---|---|---|\n| Gene set source | `\"MSigDB_Hallmark_2020\"` or GMT file | `msigdbr()` + `split()` |\n| Min gene set size | `min_size=15` | `minSize = 15` |\n| Max gene set size | `max_size=500` | `maxSize = 500` |\n| Permutations | `permutation_num=1000` | `nPermSimple = 10000` |\n| Significance threshold | `FDR q-val \u003C 0.05` | `padj \u003C 0.05` |\n| Rank metric | log2FC, signed -log10(p), or MOFA weight | Same |\n\n---\n\n## 5. Consensus Clustering\n\n### Python — scikit-learn based consensus\n\n```python\nimport numpy as np\nfrom sklearn.cluster import KMeans\nfrom sklearn.metrics import silhouette_score\n\ndef consensus_clustering(data, k_range=range(2, 9), n_iterations=100, seed=42):\n    \"\"\"Run consensus clustering over a range of k values.\n    data: samples x features array. Returns dict mapping k to results.\n    \"\"\"\n    rng = np.random.default_rng(seed)\n    n_samples = data.shape[0]\n    results = {}\n\n    for k in k_range:\n        co_occurrence = np.zeros((n_samples, n_samples))\n        co_sampled = np.zeros((n_samples, n_samples))\n\n        for _ in range(n_iterations):\n            # Subsample 80% of samples\n            idx = rng.choice(n_samples, size=int(0.8 * n_samples), replace=False)\n            km = KMeans(n_clusters=k, n_init=10, random_state=rng.integers(1e6))\n            labels = km.fit_predict(data[idx])\n\n            for i in range(len(idx)):\n                for j in range(i + 1, len(idx)):\n                    co_sampled[idx[i], idx[j]] += 1\n                    co_sampled[idx[j], idx[i]] += 1\n                    if labels[i] == labels[j]:\n                        co_occurrence[idx[i], idx[j]] += 1\n                        co_occurrence[idx[j], idx[i]] += 1\n\n        # Consensus matrix\n        with np.errstate(divide=\"ignore\", invalid=\"ignore\"):\n            consensus = np.where(co_sampled > 0, co_occurrence \u002F co_sampled, 0)\n\n        # Final clustering on consensus matrix\n        km_final = KMeans(n_clusters=k, n_init=10, random_state=seed)\n        final_labels = km_final.fit_predict(1 - consensus)  # distance = 1 - consensus\n        sil = silhouette_score(1 - consensus, final_labels, metric=\"precomputed\")\n\n        results[k] = {\"consensus_matrix\": consensus, \"silhouette\": sil, \"labels\": final_labels}\n        print(f\"k={k}: silhouette={sil:.3f}\")\n\n    return results\n\n# Usage with MOFA factors\n# factors: samples x factors array from MOFA\nresults = consensus_clustering(factors, k_range=range(2, 9))\n\n# Select optimal k by maximum silhouette score\noptimal_k = max(results, key=lambda k: results[k][\"silhouette\"])\nprint(f\"Optimal k: {optimal_k}\")\n```\n\n### R — ConsensusClusterPlus\n\n```r\nlibrary(ConsensusClusterPlus)\n# input_mat: features x samples\nresults \u003C- ConsensusClusterPlus(\n  d = input_mat,\n  maxK = 8,\n  reps = 1000,\n  pItem = 0.8,        # proportion of samples to subsample\n  pFeature = 1,       # use all features\n  clusterAlg = \"km\",  # k-means\n  distance = \"euclidean\",\n  seed = 42,\n  plot = \"pdf\",\n  title = \"consensus_clustering\"\n)\n\n# Inspect consensus CDF and delta area plots in output PDF\n# Select k where CDF curve is flattest (highest consensus)\n```\n\n### Consensus Clustering Parameter Table\n\n| Parameter | Python (custom) | R (ConsensusClusterPlus) |\n|---|---|---|\n| k range | `k_range=range(2, 9)` | `maxK = 8` |\n| Iterations | `n_iterations=100` | `reps = 1000` |\n| Subsample fraction | 0.8 (hardcoded) | `pItem = 0.8` |\n| Algorithm | KMeans | `clusterAlg = \"km\"` |\n| Selection criterion | Silhouette score | CDF delta area plot |\n\n\n---\n\n## Common Mistakes\n\n- **Wrong:** Mapping gene IDs using symbol-based joins without handling duplicates or deprecated symbols\n  **Right:** Use HGNC ID or Ensembl stable ID as the primary key; resolve ambiguous symbols via the HGNC multi-symbol checker\n  **Why:** Gene symbols are not unique (e.g., \"MARCH1\" was renamed to \"MARCHF1\") — symbol joins silently drop or duplicate rows\n\n- **Wrong:** Running ComBat without including biological covariates in the model matrix\n  **Right:** Always pass `mod = model.matrix(~ disease_status + sex, data=meta)` to protect biological signal\n  **Why:** Without protected covariates, ComBat removes biological variation that correlates with batch\n\n- **Wrong:** Using `mofapy2` with raw counts instead of normalized, variance-stabilized data\n  **Right:** Apply log2(CPM+1) or VST to RNA-seq counts before passing to MOFA; use log2 intensity for proteomics\n  **Why:** MOFA assumes Gaussian-distributed continuous data — raw counts violate this and produce meaningless factors\n\n- **Wrong:** Running gseapy\u002Ffgsea with a gene list ranked by fold change alone (no significance weighting)\n  **Right:** Rank by `-log10(p) × sign(log2FC)` or use the Wald statistic from DESeq2\u002Flimma\n  **Why:** Fold-change-only ranking treats noisy large-FC genes the same as significant ones, inflating false enrichments\n\n- **Wrong:** Using default `min_size=1` in fgsea, allowing tiny gene sets to appear significant\n  **Right:** Set `minSize=15, maxSize=500` to filter gene sets to biologically interpretable sizes\n  **Why:** Very small gene sets produce unstable enrichment scores; very large sets are too generic to be informative\n",{"data":50,"body":65},{"name":4,"description":6,"usage":51,"version":52,"validated_against":53,"tags":59},"Invoke to generate executable code for multi-omics ID mapping, batch correction, factor analysis, enrichment, and consensus clustering.","1.0.0",{"date":54,"packages":55},"2025-01-15",{"mofa2":56,"combat":57,"gseapy":58},"1.12","0.3.4","1.1",[60,61,62,63,64],"skill","category:pipeline","multi-omics","etl","hcls",{"type":66,"children":67},"root",[68,77,84,90,96,116,122,126,132,160,166,173,399,405,530,536,665,668,674,680,841,847,1023,1029,1163,1166,1172,1178,1519,1525,1695,1701,1915,1918,1924,1930,2100,2106,2300,2306,2490,2493,2499,2505,2919,2925,3066,3072,3212,3215,3221,3373],{"type":69,"tag":70,"props":71,"children":73},"element","h1",{"id":72},"multi-omics-pipeline-pipeline-skill",[74],{"type":75,"value":76},"text","Multi-Omics Pipeline — Pipeline Skill",{"type":69,"tag":78,"props":79,"children":81},"h2",{"id":80},"overview",[82],{"type":75,"value":83},"Overview",{"type":69,"tag":85,"props":86,"children":87},"p",{},[88],{"type":75,"value":89},"Provide deterministic, copy-paste-ready code for multi-omics data processing tasks: ID mapping,\nbatch correction, integration via MOFA2\u002Fmofapy2, enrichment analysis, and consensus clustering.",{"type":69,"tag":78,"props":91,"children":93},{"id":92},"usage",[94],{"type":75,"value":95},"Usage",{"type":69,"tag":97,"props":98,"children":99},"ul",{},[100,106,111],{"type":69,"tag":101,"props":102,"children":103},"li",{},[104],{"type":75,"value":105},"Map gene identifiers across HGNC, Ensembl, and UniProt systems",{"type":69,"tag":101,"props":107,"children":108},{},[109],{"type":75,"value":110},"Run batch correction (ComBat\u002FComBat-seq) and multi-omic factor analysis (MOFA2\u002Fmofapy2)",{"type":69,"tag":101,"props":112,"children":113},{},[114],{"type":75,"value":115},"Perform GSEA enrichment and consensus clustering on integrated data",{"type":69,"tag":78,"props":117,"children":119},{"id":118},"core-concepts",[120],{"type":75,"value":121},"Core Concepts",{"type":69,"tag":123,"props":124,"children":125},"hr",{},[],{"type":69,"tag":78,"props":127,"children":129},{"id":128},"response-format",[130],{"type":75,"value":131},"Response Format",{"type":69,"tag":97,"props":133,"children":134},{},[135,140,145,150,155],{"type":69,"tag":101,"props":136,"children":137},{},[138],{"type":75,"value":139},"Lead with the command or code the user needs — explain after",{"type":69,"tag":101,"props":141,"children":142},{},[143],{"type":75,"value":144},"Structure as: confirm inputs → working code → key parameters explained → gotchas",{"type":69,"tag":101,"props":146,"children":147},{},[148],{"type":75,"value":149},"One complete working example per task; do not show every alternative",{"type":69,"tag":101,"props":151,"children":152},{},[153],{"type":75,"value":154},"Keep code comments minimal and functional (what, not why-it-exists)",{"type":69,"tag":101,"props":156,"children":157},{},[158],{"type":75,"value":159},"Target: 50-100 lines of code with brief surrounding explanation",{"type":69,"tag":78,"props":161,"children":163},{"id":162},"_1-id-mapping",[164],{"type":75,"value":165},"1. ID Mapping",{"type":69,"tag":167,"props":168,"children":170},"h3",{"id":169},"_1a-python-hgnc-symbol-ensembl-uniprot",[171],{"type":75,"value":172},"1a. Python — HGNC Symbol ↔ Ensembl ↔ UniProt",{"type":69,"tag":174,"props":175,"children":180},"pre",{"className":176,"code":177,"language":178,"meta":179,"style":179},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import pandas as pd\nimport mygene\n\nmg = mygene.MyGeneInfo()\n\n# Input: list of HGNC symbols\ngenes = [\"TP53\", \"BRCA1\", \"EGFR\", \"KRAS\"]\n\n# Query multiple ID types at once\nresult = mg.querymany(\n    genes,\n    scopes=\"symbol\",\n    fields=\"ensembl.gene,uniprot.Swiss-Prot\",\n    species=\"human\",\n    returnall=True,\n)\n\ndf = pd.DataFrame(result[\"out\"])\n# Handle many-to-many: explode nested Ensembl IDs\ndf_ensembl = df.explode(\"ensembl\")\ndf_ensembl[\"ensembl_id\"] = df_ensembl[\"ensembl\"].apply(\n    lambda x: x[\"gene\"] if isinstance(x, dict) else None\n)\nprint(df_ensembl[[\"query\", \"ensembl_id\"]].dropna())\n","python","",[181],{"type":69,"tag":182,"props":183,"children":184},"code",{"__ignoreMap":179},[185,196,205,215,223,231,240,249,257,266,275,284,293,302,311,320,329,337,346,355,364,373,382,390],{"type":69,"tag":186,"props":187,"children":190},"span",{"class":188,"line":189},"line",1,[191],{"type":69,"tag":186,"props":192,"children":193},{},[194],{"type":75,"value":195},"import pandas as pd\n",{"type":69,"tag":186,"props":197,"children":199},{"class":188,"line":198},2,[200],{"type":69,"tag":186,"props":201,"children":202},{},[203],{"type":75,"value":204},"import mygene\n",{"type":69,"tag":186,"props":206,"children":208},{"class":188,"line":207},3,[209],{"type":69,"tag":186,"props":210,"children":212},{"emptyLinePlaceholder":211},true,[213],{"type":75,"value":214},"\n",{"type":69,"tag":186,"props":216,"children":217},{"class":188,"line":26},[218],{"type":69,"tag":186,"props":219,"children":220},{},[221],{"type":75,"value":222},"mg = mygene.MyGeneInfo()\n",{"type":69,"tag":186,"props":224,"children":226},{"class":188,"line":225},5,[227],{"type":69,"tag":186,"props":228,"children":229},{"emptyLinePlaceholder":211},[230],{"type":75,"value":214},{"type":69,"tag":186,"props":232,"children":234},{"class":188,"line":233},6,[235],{"type":69,"tag":186,"props":236,"children":237},{},[238],{"type":75,"value":239},"# Input: list of HGNC symbols\n",{"type":69,"tag":186,"props":241,"children":243},{"class":188,"line":242},7,[244],{"type":69,"tag":186,"props":245,"children":246},{},[247],{"type":75,"value":248},"genes = [\"TP53\", \"BRCA1\", \"EGFR\", \"KRAS\"]\n",{"type":69,"tag":186,"props":250,"children":252},{"class":188,"line":251},8,[253],{"type":69,"tag":186,"props":254,"children":255},{"emptyLinePlaceholder":211},[256],{"type":75,"value":214},{"type":69,"tag":186,"props":258,"children":260},{"class":188,"line":259},9,[261],{"type":69,"tag":186,"props":262,"children":263},{},[264],{"type":75,"value":265},"# Query multiple ID types at once\n",{"type":69,"tag":186,"props":267,"children":269},{"class":188,"line":268},10,[270],{"type":69,"tag":186,"props":271,"children":272},{},[273],{"type":75,"value":274},"result = mg.querymany(\n",{"type":69,"tag":186,"props":276,"children":278},{"class":188,"line":277},11,[279],{"type":69,"tag":186,"props":280,"children":281},{},[282],{"type":75,"value":283},"    genes,\n",{"type":69,"tag":186,"props":285,"children":287},{"class":188,"line":286},12,[288],{"type":69,"tag":186,"props":289,"children":290},{},[291],{"type":75,"value":292},"    scopes=\"symbol\",\n",{"type":69,"tag":186,"props":294,"children":296},{"class":188,"line":295},13,[297],{"type":69,"tag":186,"props":298,"children":299},{},[300],{"type":75,"value":301},"    fields=\"ensembl.gene,uniprot.Swiss-Prot\",\n",{"type":69,"tag":186,"props":303,"children":305},{"class":188,"line":304},14,[306],{"type":69,"tag":186,"props":307,"children":308},{},[309],{"type":75,"value":310},"    species=\"human\",\n",{"type":69,"tag":186,"props":312,"children":314},{"class":188,"line":313},15,[315],{"type":69,"tag":186,"props":316,"children":317},{},[318],{"type":75,"value":319},"    returnall=True,\n",{"type":69,"tag":186,"props":321,"children":323},{"class":188,"line":322},16,[324],{"type":69,"tag":186,"props":325,"children":326},{},[327],{"type":75,"value":328},")\n",{"type":69,"tag":186,"props":330,"children":332},{"class":188,"line":331},17,[333],{"type":69,"tag":186,"props":334,"children":335},{"emptyLinePlaceholder":211},[336],{"type":75,"value":214},{"type":69,"tag":186,"props":338,"children":340},{"class":188,"line":339},18,[341],{"type":69,"tag":186,"props":342,"children":343},{},[344],{"type":75,"value":345},"df = pd.DataFrame(result[\"out\"])\n",{"type":69,"tag":186,"props":347,"children":349},{"class":188,"line":348},19,[350],{"type":69,"tag":186,"props":351,"children":352},{},[353],{"type":75,"value":354},"# Handle many-to-many: explode nested Ensembl IDs\n",{"type":69,"tag":186,"props":356,"children":358},{"class":188,"line":357},20,[359],{"type":69,"tag":186,"props":360,"children":361},{},[362],{"type":75,"value":363},"df_ensembl = df.explode(\"ensembl\")\n",{"type":69,"tag":186,"props":365,"children":367},{"class":188,"line":366},21,[368],{"type":69,"tag":186,"props":369,"children":370},{},[371],{"type":75,"value":372},"df_ensembl[\"ensembl_id\"] = df_ensembl[\"ensembl\"].apply(\n",{"type":69,"tag":186,"props":374,"children":376},{"class":188,"line":375},22,[377],{"type":69,"tag":186,"props":378,"children":379},{},[380],{"type":75,"value":381},"    lambda x: x[\"gene\"] if isinstance(x, dict) else None\n",{"type":69,"tag":186,"props":383,"children":385},{"class":188,"line":384},23,[386],{"type":69,"tag":186,"props":387,"children":388},{},[389],{"type":75,"value":328},{"type":69,"tag":186,"props":391,"children":393},{"class":188,"line":392},24,[394],{"type":69,"tag":186,"props":395,"children":396},{},[397],{"type":75,"value":398},"print(df_ensembl[[\"query\", \"ensembl_id\"]].dropna())\n",{"type":69,"tag":167,"props":400,"children":402},{"id":401},"_1b-r-biomart",[403],{"type":75,"value":404},"1b. R — biomaRt",{"type":69,"tag":174,"props":406,"children":410},{"className":407,"code":408,"language":409,"meta":179,"style":179},"language-r shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","library(biomaRt)\n\nensembl \u003C- useEnsembl(biomart = \"genes\", dataset = \"hsapiens_gene_ensembl\")\n\n# Map HGNC symbols to Ensembl gene IDs and UniProt accessions\nmapping \u003C- getBM(\n  attributes = c(\"hgnc_symbol\", \"ensembl_gene_id\", \"uniprotswissprot\"),\n  filters = \"hgnc_symbol\",\n  values = c(\"TP53\", \"BRCA1\", \"EGFR\", \"KRAS\"),\n  mart = ensembl\n)\n\n# Remove rows with empty UniProt\nmapping \u003C- mapping[mapping$uniprotswissprot != \"\", ]\nprint(mapping)\n","r",[411],{"type":69,"tag":182,"props":412,"children":413},{"__ignoreMap":179},[414,422,429,437,444,452,460,468,476,484,492,499,506,514,522],{"type":69,"tag":186,"props":415,"children":416},{"class":188,"line":189},[417],{"type":69,"tag":186,"props":418,"children":419},{},[420],{"type":75,"value":421},"library(biomaRt)\n",{"type":69,"tag":186,"props":423,"children":424},{"class":188,"line":198},[425],{"type":69,"tag":186,"props":426,"children":427},{"emptyLinePlaceholder":211},[428],{"type":75,"value":214},{"type":69,"tag":186,"props":430,"children":431},{"class":188,"line":207},[432],{"type":69,"tag":186,"props":433,"children":434},{},[435],{"type":75,"value":436},"ensembl \u003C- useEnsembl(biomart = \"genes\", dataset = \"hsapiens_gene_ensembl\")\n",{"type":69,"tag":186,"props":438,"children":439},{"class":188,"line":26},[440],{"type":69,"tag":186,"props":441,"children":442},{"emptyLinePlaceholder":211},[443],{"type":75,"value":214},{"type":69,"tag":186,"props":445,"children":446},{"class":188,"line":225},[447],{"type":69,"tag":186,"props":448,"children":449},{},[450],{"type":75,"value":451},"# Map HGNC symbols to Ensembl gene IDs and UniProt accessions\n",{"type":69,"tag":186,"props":453,"children":454},{"class":188,"line":233},[455],{"type":69,"tag":186,"props":456,"children":457},{},[458],{"type":75,"value":459},"mapping \u003C- getBM(\n",{"type":69,"tag":186,"props":461,"children":462},{"class":188,"line":242},[463],{"type":69,"tag":186,"props":464,"children":465},{},[466],{"type":75,"value":467},"  attributes = c(\"hgnc_symbol\", \"ensembl_gene_id\", \"uniprotswissprot\"),\n",{"type":69,"tag":186,"props":469,"children":470},{"class":188,"line":251},[471],{"type":69,"tag":186,"props":472,"children":473},{},[474],{"type":75,"value":475},"  filters = \"hgnc_symbol\",\n",{"type":69,"tag":186,"props":477,"children":478},{"class":188,"line":259},[479],{"type":69,"tag":186,"props":480,"children":481},{},[482],{"type":75,"value":483},"  values = c(\"TP53\", \"BRCA1\", \"EGFR\", \"KRAS\"),\n",{"type":69,"tag":186,"props":485,"children":486},{"class":188,"line":268},[487],{"type":69,"tag":186,"props":488,"children":489},{},[490],{"type":75,"value":491},"  mart = ensembl\n",{"type":69,"tag":186,"props":493,"children":494},{"class":188,"line":277},[495],{"type":69,"tag":186,"props":496,"children":497},{},[498],{"type":75,"value":328},{"type":69,"tag":186,"props":500,"children":501},{"class":188,"line":286},[502],{"type":69,"tag":186,"props":503,"children":504},{"emptyLinePlaceholder":211},[505],{"type":75,"value":214},{"type":69,"tag":186,"props":507,"children":508},{"class":188,"line":295},[509],{"type":69,"tag":186,"props":510,"children":511},{},[512],{"type":75,"value":513},"# Remove rows with empty UniProt\n",{"type":69,"tag":186,"props":515,"children":516},{"class":188,"line":304},[517],{"type":69,"tag":186,"props":518,"children":519},{},[520],{"type":75,"value":521},"mapping \u003C- mapping[mapping$uniprotswissprot != \"\", ]\n",{"type":69,"tag":186,"props":523,"children":524},{"class":188,"line":313},[525],{"type":69,"tag":186,"props":526,"children":527},{},[528],{"type":75,"value":529},"print(mapping)\n",{"type":69,"tag":167,"props":531,"children":533},{"id":532},"id-mapping-parameter-table",[534],{"type":75,"value":535},"ID Mapping Parameter Table",{"type":69,"tag":537,"props":538,"children":539},"table",{},[540,564],{"type":69,"tag":541,"props":542,"children":543},"thead",{},[544],{"type":69,"tag":545,"props":546,"children":547},"tr",{},[548,554,559],{"type":69,"tag":549,"props":550,"children":551},"th",{},[552],{"type":75,"value":553},"Parameter",{"type":69,"tag":549,"props":555,"children":556},{},[557],{"type":75,"value":558},"Python (mygene)",{"type":69,"tag":549,"props":560,"children":561},{},[562],{"type":75,"value":563},"R (biomaRt)",{"type":69,"tag":565,"props":566,"children":567},"tbody",{},[568,595,621,647],{"type":69,"tag":545,"props":569,"children":570},{},[571,577,586],{"type":69,"tag":572,"props":573,"children":574},"td",{},[575],{"type":75,"value":576},"Input ID type",{"type":69,"tag":572,"props":578,"children":579},{},[580],{"type":69,"tag":182,"props":581,"children":583},{"className":582},[],[584],{"type":75,"value":585},"scopes=\"symbol\"",{"type":69,"tag":572,"props":587,"children":588},{},[589],{"type":69,"tag":182,"props":590,"children":592},{"className":591},[],[593],{"type":75,"value":594},"filters = \"hgnc_symbol\"",{"type":69,"tag":545,"props":596,"children":597},{},[598,603,612],{"type":69,"tag":572,"props":599,"children":600},{},[601],{"type":75,"value":602},"Output ID types",{"type":69,"tag":572,"props":604,"children":605},{},[606],{"type":69,"tag":182,"props":607,"children":609},{"className":608},[],[610],{"type":75,"value":611},"fields=\"ensembl.gene,uniprot.Swiss-Prot\"",{"type":69,"tag":572,"props":613,"children":614},{},[615],{"type":69,"tag":182,"props":616,"children":618},{"className":617},[],[619],{"type":75,"value":620},"attributes = c(\"ensembl_gene_id\", \"uniprotswissprot\")",{"type":69,"tag":545,"props":622,"children":623},{},[624,629,638],{"type":69,"tag":572,"props":625,"children":626},{},[627],{"type":75,"value":628},"Species filter",{"type":69,"tag":572,"props":630,"children":631},{},[632],{"type":69,"tag":182,"props":633,"children":635},{"className":634},[],[636],{"type":75,"value":637},"species=\"human\"",{"type":69,"tag":572,"props":639,"children":640},{},[641],{"type":69,"tag":182,"props":642,"children":644},{"className":643},[],[645],{"type":75,"value":646},"dataset = \"hsapiens_gene_ensembl\"",{"type":69,"tag":545,"props":648,"children":649},{},[650,655,660],{"type":69,"tag":572,"props":651,"children":652},{},[653],{"type":75,"value":654},"Many-to-many handling",{"type":69,"tag":572,"props":656,"children":657},{},[658],{"type":75,"value":659},"Explode nested lists",{"type":69,"tag":572,"props":661,"children":662},{},[663],{"type":75,"value":664},"Multiple rows returned automatically",{"type":69,"tag":123,"props":666,"children":667},{},[],{"type":69,"tag":78,"props":669,"children":671},{"id":670},"_2-batch-correction",[672],{"type":75,"value":673},"2. Batch Correction",{"type":69,"tag":167,"props":675,"children":677},{"id":676},"_2a-python-combat-pycombat",[678],{"type":75,"value":679},"2a. Python — ComBat (pycombat)",{"type":69,"tag":174,"props":681,"children":683},{"className":176,"code":682,"language":178,"meta":179,"style":179},"from combat.pycombat import pycombat\nimport pandas as pd\nimport numpy as np\n\n# expression_df: genes (rows) x samples (columns), log-transformed\n# batch: list of batch labels, same order as columns\n# covariates: DataFrame with biological covariates to protect\n\nexpression_df = pd.read_csv(\"expression_matrix.csv\", index_col=0)\nbatch = [1, 1, 1, 2, 2, 2, 3, 3, 3]  # batch labels per sample\n\n# Protect biological covariate (e.g., disease status)\ncovar_df = pd.DataFrame({\"disease\": [0, 0, 1, 0, 1, 1, 0, 1, 1]})\n\ncorrected = pycombat(\n    expression_df,\n    batch,\n    mod=covar_df,       # biological covariates to protect\n    par_prior=True,     # parametric adjustment (default)\n)\n",[684],{"type":69,"tag":182,"props":685,"children":686},{"__ignoreMap":179},[687,695,702,710,717,725,733,741,748,756,764,771,779,787,794,802,810,818,826,834],{"type":69,"tag":186,"props":688,"children":689},{"class":188,"line":189},[690],{"type":69,"tag":186,"props":691,"children":692},{},[693],{"type":75,"value":694},"from combat.pycombat import pycombat\n",{"type":69,"tag":186,"props":696,"children":697},{"class":188,"line":198},[698],{"type":69,"tag":186,"props":699,"children":700},{},[701],{"type":75,"value":195},{"type":69,"tag":186,"props":703,"children":704},{"class":188,"line":207},[705],{"type":69,"tag":186,"props":706,"children":707},{},[708],{"type":75,"value":709},"import numpy as np\n",{"type":69,"tag":186,"props":711,"children":712},{"class":188,"line":26},[713],{"type":69,"tag":186,"props":714,"children":715},{"emptyLinePlaceholder":211},[716],{"type":75,"value":214},{"type":69,"tag":186,"props":718,"children":719},{"class":188,"line":225},[720],{"type":69,"tag":186,"props":721,"children":722},{},[723],{"type":75,"value":724},"# expression_df: genes (rows) x samples (columns), log-transformed\n",{"type":69,"tag":186,"props":726,"children":727},{"class":188,"line":233},[728],{"type":69,"tag":186,"props":729,"children":730},{},[731],{"type":75,"value":732},"# batch: list of batch labels, same order as columns\n",{"type":69,"tag":186,"props":734,"children":735},{"class":188,"line":242},[736],{"type":69,"tag":186,"props":737,"children":738},{},[739],{"type":75,"value":740},"# covariates: DataFrame with biological covariates to protect\n",{"type":69,"tag":186,"props":742,"children":743},{"class":188,"line":251},[744],{"type":69,"tag":186,"props":745,"children":746},{"emptyLinePlaceholder":211},[747],{"type":75,"value":214},{"type":69,"tag":186,"props":749,"children":750},{"class":188,"line":259},[751],{"type":69,"tag":186,"props":752,"children":753},{},[754],{"type":75,"value":755},"expression_df = pd.read_csv(\"expression_matrix.csv\", index_col=0)\n",{"type":69,"tag":186,"props":757,"children":758},{"class":188,"line":268},[759],{"type":69,"tag":186,"props":760,"children":761},{},[762],{"type":75,"value":763},"batch = [1, 1, 1, 2, 2, 2, 3, 3, 3]  # batch labels per sample\n",{"type":69,"tag":186,"props":765,"children":766},{"class":188,"line":277},[767],{"type":69,"tag":186,"props":768,"children":769},{"emptyLinePlaceholder":211},[770],{"type":75,"value":214},{"type":69,"tag":186,"props":772,"children":773},{"class":188,"line":286},[774],{"type":69,"tag":186,"props":775,"children":776},{},[777],{"type":75,"value":778},"# Protect biological covariate (e.g., disease status)\n",{"type":69,"tag":186,"props":780,"children":781},{"class":188,"line":295},[782],{"type":69,"tag":186,"props":783,"children":784},{},[785],{"type":75,"value":786},"covar_df = pd.DataFrame({\"disease\": [0, 0, 1, 0, 1, 1, 0, 1, 1]})\n",{"type":69,"tag":186,"props":788,"children":789},{"class":188,"line":304},[790],{"type":69,"tag":186,"props":791,"children":792},{"emptyLinePlaceholder":211},[793],{"type":75,"value":214},{"type":69,"tag":186,"props":795,"children":796},{"class":188,"line":313},[797],{"type":69,"tag":186,"props":798,"children":799},{},[800],{"type":75,"value":801},"corrected = pycombat(\n",{"type":69,"tag":186,"props":803,"children":804},{"class":188,"line":322},[805],{"type":69,"tag":186,"props":806,"children":807},{},[808],{"type":75,"value":809},"    expression_df,\n",{"type":69,"tag":186,"props":811,"children":812},{"class":188,"line":331},[813],{"type":69,"tag":186,"props":814,"children":815},{},[816],{"type":75,"value":817},"    batch,\n",{"type":69,"tag":186,"props":819,"children":820},{"class":188,"line":339},[821],{"type":69,"tag":186,"props":822,"children":823},{},[824],{"type":75,"value":825},"    mod=covar_df,       # biological covariates to protect\n",{"type":69,"tag":186,"props":827,"children":828},{"class":188,"line":348},[829],{"type":69,"tag":186,"props":830,"children":831},{},[832],{"type":75,"value":833},"    par_prior=True,     # parametric adjustment (default)\n",{"type":69,"tag":186,"props":835,"children":836},{"class":188,"line":357},[837],{"type":69,"tag":186,"props":838,"children":839},{},[840],{"type":75,"value":328},{"type":69,"tag":167,"props":842,"children":844},{"id":843},"_2b-r-combat-combat-seq",[845],{"type":75,"value":846},"2b. R — ComBat \u002F ComBat-seq",{"type":69,"tag":174,"props":848,"children":850},{"className":407,"code":849,"language":409,"meta":179,"style":179},"library(sva)\n\n# For continuous data (log-transformed expression, protein intensity)\n# expr_mat: genes x samples matrix\n# batch: vector of batch labels\n# mod: model matrix with biological covariates to protect\n\nmod \u003C- model.matrix(~ disease_status, data = sample_info)\n\ncorrected \u003C- ComBat(\n  dat = expr_mat,\n  batch = sample_info$batch,\n  mod = mod,\n  par.prior = TRUE  # parametric\n)\n\n# For count data (RNA-seq raw counts) — use ComBat-seq\ncorrected_counts \u003C- ComBat_seq(\n  counts = count_mat,\n  batch = sample_info$batch,\n  group = sample_info$disease_status  # biological variable to protect\n)\n",[851],{"type":69,"tag":182,"props":852,"children":853},{"__ignoreMap":179},[854,862,869,877,885,893,901,908,916,923,931,939,947,955,963,970,977,985,993,1001,1008,1016],{"type":69,"tag":186,"props":855,"children":856},{"class":188,"line":189},[857],{"type":69,"tag":186,"props":858,"children":859},{},[860],{"type":75,"value":861},"library(sva)\n",{"type":69,"tag":186,"props":863,"children":864},{"class":188,"line":198},[865],{"type":69,"tag":186,"props":866,"children":867},{"emptyLinePlaceholder":211},[868],{"type":75,"value":214},{"type":69,"tag":186,"props":870,"children":871},{"class":188,"line":207},[872],{"type":69,"tag":186,"props":873,"children":874},{},[875],{"type":75,"value":876},"# For continuous data (log-transformed expression, protein intensity)\n",{"type":69,"tag":186,"props":878,"children":879},{"class":188,"line":26},[880],{"type":69,"tag":186,"props":881,"children":882},{},[883],{"type":75,"value":884},"# expr_mat: genes x samples matrix\n",{"type":69,"tag":186,"props":886,"children":887},{"class":188,"line":225},[888],{"type":69,"tag":186,"props":889,"children":890},{},[891],{"type":75,"value":892},"# batch: vector of batch labels\n",{"type":69,"tag":186,"props":894,"children":895},{"class":188,"line":233},[896],{"type":69,"tag":186,"props":897,"children":898},{},[899],{"type":75,"value":900},"# mod: model matrix with biological covariates to protect\n",{"type":69,"tag":186,"props":902,"children":903},{"class":188,"line":242},[904],{"type":69,"tag":186,"props":905,"children":906},{"emptyLinePlaceholder":211},[907],{"type":75,"value":214},{"type":69,"tag":186,"props":909,"children":910},{"class":188,"line":251},[911],{"type":69,"tag":186,"props":912,"children":913},{},[914],{"type":75,"value":915},"mod \u003C- model.matrix(~ disease_status, data = sample_info)\n",{"type":69,"tag":186,"props":917,"children":918},{"class":188,"line":259},[919],{"type":69,"tag":186,"props":920,"children":921},{"emptyLinePlaceholder":211},[922],{"type":75,"value":214},{"type":69,"tag":186,"props":924,"children":925},{"class":188,"line":268},[926],{"type":69,"tag":186,"props":927,"children":928},{},[929],{"type":75,"value":930},"corrected \u003C- ComBat(\n",{"type":69,"tag":186,"props":932,"children":933},{"class":188,"line":277},[934],{"type":69,"tag":186,"props":935,"children":936},{},[937],{"type":75,"value":938},"  dat = expr_mat,\n",{"type":69,"tag":186,"props":940,"children":941},{"class":188,"line":286},[942],{"type":69,"tag":186,"props":943,"children":944},{},[945],{"type":75,"value":946},"  batch = sample_info$batch,\n",{"type":69,"tag":186,"props":948,"children":949},{"class":188,"line":295},[950],{"type":69,"tag":186,"props":951,"children":952},{},[953],{"type":75,"value":954},"  mod = mod,\n",{"type":69,"tag":186,"props":956,"children":957},{"class":188,"line":304},[958],{"type":69,"tag":186,"props":959,"children":960},{},[961],{"type":75,"value":962},"  par.prior = TRUE  # parametric\n",{"type":69,"tag":186,"props":964,"children":965},{"class":188,"line":313},[966],{"type":69,"tag":186,"props":967,"children":968},{},[969],{"type":75,"value":328},{"type":69,"tag":186,"props":971,"children":972},{"class":188,"line":322},[973],{"type":69,"tag":186,"props":974,"children":975},{"emptyLinePlaceholder":211},[976],{"type":75,"value":214},{"type":69,"tag":186,"props":978,"children":979},{"class":188,"line":331},[980],{"type":69,"tag":186,"props":981,"children":982},{},[983],{"type":75,"value":984},"# For count data (RNA-seq raw counts) — use ComBat-seq\n",{"type":69,"tag":186,"props":986,"children":987},{"class":188,"line":339},[988],{"type":69,"tag":186,"props":989,"children":990},{},[991],{"type":75,"value":992},"corrected_counts \u003C- ComBat_seq(\n",{"type":69,"tag":186,"props":994,"children":995},{"class":188,"line":348},[996],{"type":69,"tag":186,"props":997,"children":998},{},[999],{"type":75,"value":1000},"  counts = count_mat,\n",{"type":69,"tag":186,"props":1002,"children":1003},{"class":188,"line":357},[1004],{"type":69,"tag":186,"props":1005,"children":1006},{},[1007],{"type":75,"value":946},{"type":69,"tag":186,"props":1009,"children":1010},{"class":188,"line":366},[1011],{"type":69,"tag":186,"props":1012,"children":1013},{},[1014],{"type":75,"value":1015},"  group = sample_info$disease_status  # biological variable to protect\n",{"type":69,"tag":186,"props":1017,"children":1018},{"class":188,"line":375},[1019],{"type":69,"tag":186,"props":1020,"children":1021},{},[1022],{"type":75,"value":328},{"type":69,"tag":167,"props":1024,"children":1026},{"id":1025},"batch-correction-parameter-table",[1027],{"type":75,"value":1028},"Batch Correction Parameter Table",{"type":69,"tag":537,"props":1030,"children":1031},{},[1032,1052],{"type":69,"tag":541,"props":1033,"children":1034},{},[1035],{"type":69,"tag":545,"props":1036,"children":1037},{},[1038,1042,1047],{"type":69,"tag":549,"props":1039,"children":1040},{},[1041],{"type":75,"value":553},{"type":69,"tag":549,"props":1043,"children":1044},{},[1045],{"type":75,"value":1046},"ComBat (continuous)",{"type":69,"tag":549,"props":1048,"children":1049},{},[1050],{"type":75,"value":1051},"ComBat-seq (counts)",{"type":69,"tag":565,"props":1053,"children":1054},{},[1055,1073,1097,1127,1145],{"type":69,"tag":545,"props":1056,"children":1057},{},[1058,1063,1068],{"type":69,"tag":572,"props":1059,"children":1060},{},[1061],{"type":75,"value":1062},"Input",{"type":69,"tag":572,"props":1064,"children":1065},{},[1066],{"type":75,"value":1067},"Log-transformed matrix",{"type":69,"tag":572,"props":1069,"children":1070},{},[1071],{"type":75,"value":1072},"Raw count matrix (integers)",{"type":69,"tag":545,"props":1074,"children":1075},{},[1076,1081,1092],{"type":69,"tag":572,"props":1077,"children":1078},{},[1079],{"type":75,"value":1080},"Parametric prior",{"type":69,"tag":572,"props":1082,"children":1083},{},[1084,1090],{"type":69,"tag":182,"props":1085,"children":1087},{"className":1086},[],[1088],{"type":75,"value":1089},"par.prior = TRUE",{"type":75,"value":1091}," (default)",{"type":69,"tag":572,"props":1093,"children":1094},{},[1095],{"type":75,"value":1096},"Not applicable",{"type":69,"tag":545,"props":1098,"children":1099},{},[1100,1105,1116],{"type":69,"tag":572,"props":1101,"children":1102},{},[1103],{"type":75,"value":1104},"Biological covariate",{"type":69,"tag":572,"props":1106,"children":1107},{},[1108,1114],{"type":69,"tag":182,"props":1109,"children":1111},{"className":1110},[],[1112],{"type":75,"value":1113},"mod",{"type":75,"value":1115}," (model matrix)",{"type":69,"tag":572,"props":1117,"children":1118},{},[1119,1125],{"type":69,"tag":182,"props":1120,"children":1122},{"className":1121},[],[1123],{"type":75,"value":1124},"group",{"type":75,"value":1126}," (vector)",{"type":69,"tag":545,"props":1128,"children":1129},{},[1130,1135,1140],{"type":69,"tag":572,"props":1131,"children":1132},{},[1133],{"type":75,"value":1134},"Output",{"type":69,"tag":572,"props":1136,"children":1137},{},[1138],{"type":75,"value":1139},"Corrected continuous matrix",{"type":69,"tag":572,"props":1141,"children":1142},{},[1143],{"type":75,"value":1144},"Corrected count matrix",{"type":69,"tag":545,"props":1146,"children":1147},{},[1148,1153,1158],{"type":69,"tag":572,"props":1149,"children":1150},{},[1151],{"type":75,"value":1152},"When to use",{"type":69,"tag":572,"props":1154,"children":1155},{},[1156],{"type":75,"value":1157},"Proteomics, methylation M-values, log-expression",{"type":69,"tag":572,"props":1159,"children":1160},{},[1161],{"type":75,"value":1162},"RNA-seq raw counts",{"type":69,"tag":123,"props":1164,"children":1165},{},[],{"type":69,"tag":78,"props":1167,"children":1169},{"id":1168},"_3-mofa2-mofapy2-integration",[1170],{"type":75,"value":1171},"3. MOFA2 \u002F mofapy2 Integration",{"type":69,"tag":167,"props":1173,"children":1175},{"id":1174},"_3a-r-mofa2",[1176],{"type":75,"value":1177},"3a. R — MOFA2",{"type":69,"tag":174,"props":1179,"children":1181},{"className":407,"code":1180,"language":409,"meta":179,"style":179},"library(MOFA2)\n\n# Prepare data: list of matrices, one per omic layer\n# Each matrix: features x samples\ndata_list \u003C- list(\n  transcriptomics = expr_mat,   # genes x samples\n  proteomics = prot_mat,        # proteins x samples\n  methylation = meth_mat        # CpG sites x samples\n)\n\n# Create MOFA object\nmofa \u003C- create_mofa(data_list)\n\n# Set data options\ndata_opts \u003C- get_default_data_options(mofa)\n\n# Set model options\nmodel_opts \u003C- get_default_model_options(mofa)\nmodel_opts$num_factors \u003C- 20  # start with 20; inactive factors pruned automatically\n\n# Set training options\ntrain_opts \u003C- get_default_training_options(mofa)\ntrain_opts$convergence_mode \u003C- \"slow\"  # more iterations for better convergence\ntrain_opts$seed \u003C- 42\n\n# Prepare and run\nmofa \u003C- prepare_mofa(\n  mofa,\n  data_options = data_opts,\n  model_options = model_opts,\n  training_options = train_opts\n)\n\nmofa \u003C- run_mofa(mofa, outfile = \"mofa_model.hdf5\")\n\n# Inspect variance explained per factor per view\nplot_variance_explained(mofa)\n\n# Extract top features for factor 1\nweights \u003C- get_weights(mofa, views = \"transcriptomics\", factors = 1, as.data.frame = TRUE)\ntop_genes \u003C- weights[order(abs(weights$value), decreasing = TRUE), ][1:50, ]\n",[1182],{"type":69,"tag":182,"props":1183,"children":1184},{"__ignoreMap":179},[1185,1193,1200,1208,1216,1224,1232,1240,1248,1255,1262,1270,1278,1285,1293,1301,1308,1316,1324,1332,1339,1347,1355,1363,1371,1379,1388,1397,1406,1415,1424,1433,1441,1449,1458,1466,1475,1484,1492,1501,1510],{"type":69,"tag":186,"props":1186,"children":1187},{"class":188,"line":189},[1188],{"type":69,"tag":186,"props":1189,"children":1190},{},[1191],{"type":75,"value":1192},"library(MOFA2)\n",{"type":69,"tag":186,"props":1194,"children":1195},{"class":188,"line":198},[1196],{"type":69,"tag":186,"props":1197,"children":1198},{"emptyLinePlaceholder":211},[1199],{"type":75,"value":214},{"type":69,"tag":186,"props":1201,"children":1202},{"class":188,"line":207},[1203],{"type":69,"tag":186,"props":1204,"children":1205},{},[1206],{"type":75,"value":1207},"# Prepare data: list of matrices, one per omic layer\n",{"type":69,"tag":186,"props":1209,"children":1210},{"class":188,"line":26},[1211],{"type":69,"tag":186,"props":1212,"children":1213},{},[1214],{"type":75,"value":1215},"# Each matrix: features x samples\n",{"type":69,"tag":186,"props":1217,"children":1218},{"class":188,"line":225},[1219],{"type":69,"tag":186,"props":1220,"children":1221},{},[1222],{"type":75,"value":1223},"data_list \u003C- list(\n",{"type":69,"tag":186,"props":1225,"children":1226},{"class":188,"line":233},[1227],{"type":69,"tag":186,"props":1228,"children":1229},{},[1230],{"type":75,"value":1231},"  transcriptomics = expr_mat,   # genes x samples\n",{"type":69,"tag":186,"props":1233,"children":1234},{"class":188,"line":242},[1235],{"type":69,"tag":186,"props":1236,"children":1237},{},[1238],{"type":75,"value":1239},"  proteomics = prot_mat,        # proteins x samples\n",{"type":69,"tag":186,"props":1241,"children":1242},{"class":188,"line":251},[1243],{"type":69,"tag":186,"props":1244,"children":1245},{},[1246],{"type":75,"value":1247},"  methylation = meth_mat        # CpG sites x samples\n",{"type":69,"tag":186,"props":1249,"children":1250},{"class":188,"line":259},[1251],{"type":69,"tag":186,"props":1252,"children":1253},{},[1254],{"type":75,"value":328},{"type":69,"tag":186,"props":1256,"children":1257},{"class":188,"line":268},[1258],{"type":69,"tag":186,"props":1259,"children":1260},{"emptyLinePlaceholder":211},[1261],{"type":75,"value":214},{"type":69,"tag":186,"props":1263,"children":1264},{"class":188,"line":277},[1265],{"type":69,"tag":186,"props":1266,"children":1267},{},[1268],{"type":75,"value":1269},"# Create MOFA object\n",{"type":69,"tag":186,"props":1271,"children":1272},{"class":188,"line":286},[1273],{"type":69,"tag":186,"props":1274,"children":1275},{},[1276],{"type":75,"value":1277},"mofa \u003C- create_mofa(data_list)\n",{"type":69,"tag":186,"props":1279,"children":1280},{"class":188,"line":295},[1281],{"type":69,"tag":186,"props":1282,"children":1283},{"emptyLinePlaceholder":211},[1284],{"type":75,"value":214},{"type":69,"tag":186,"props":1286,"children":1287},{"class":188,"line":304},[1288],{"type":69,"tag":186,"props":1289,"children":1290},{},[1291],{"type":75,"value":1292},"# Set data options\n",{"type":69,"tag":186,"props":1294,"children":1295},{"class":188,"line":313},[1296],{"type":69,"tag":186,"props":1297,"children":1298},{},[1299],{"type":75,"value":1300},"data_opts \u003C- get_default_data_options(mofa)\n",{"type":69,"tag":186,"props":1302,"children":1303},{"class":188,"line":322},[1304],{"type":69,"tag":186,"props":1305,"children":1306},{"emptyLinePlaceholder":211},[1307],{"type":75,"value":214},{"type":69,"tag":186,"props":1309,"children":1310},{"class":188,"line":331},[1311],{"type":69,"tag":186,"props":1312,"children":1313},{},[1314],{"type":75,"value":1315},"# Set model options\n",{"type":69,"tag":186,"props":1317,"children":1318},{"class":188,"line":339},[1319],{"type":69,"tag":186,"props":1320,"children":1321},{},[1322],{"type":75,"value":1323},"model_opts \u003C- get_default_model_options(mofa)\n",{"type":69,"tag":186,"props":1325,"children":1326},{"class":188,"line":348},[1327],{"type":69,"tag":186,"props":1328,"children":1329},{},[1330],{"type":75,"value":1331},"model_opts$num_factors \u003C- 20  # start with 20; inactive factors pruned automatically\n",{"type":69,"tag":186,"props":1333,"children":1334},{"class":188,"line":357},[1335],{"type":69,"tag":186,"props":1336,"children":1337},{"emptyLinePlaceholder":211},[1338],{"type":75,"value":214},{"type":69,"tag":186,"props":1340,"children":1341},{"class":188,"line":366},[1342],{"type":69,"tag":186,"props":1343,"children":1344},{},[1345],{"type":75,"value":1346},"# Set training options\n",{"type":69,"tag":186,"props":1348,"children":1349},{"class":188,"line":375},[1350],{"type":69,"tag":186,"props":1351,"children":1352},{},[1353],{"type":75,"value":1354},"train_opts \u003C- get_default_training_options(mofa)\n",{"type":69,"tag":186,"props":1356,"children":1357},{"class":188,"line":384},[1358],{"type":69,"tag":186,"props":1359,"children":1360},{},[1361],{"type":75,"value":1362},"train_opts$convergence_mode \u003C- \"slow\"  # more iterations for better convergence\n",{"type":69,"tag":186,"props":1364,"children":1365},{"class":188,"line":392},[1366],{"type":69,"tag":186,"props":1367,"children":1368},{},[1369],{"type":75,"value":1370},"train_opts$seed \u003C- 42\n",{"type":69,"tag":186,"props":1372,"children":1374},{"class":188,"line":1373},25,[1375],{"type":69,"tag":186,"props":1376,"children":1377},{"emptyLinePlaceholder":211},[1378],{"type":75,"value":214},{"type":69,"tag":186,"props":1380,"children":1382},{"class":188,"line":1381},26,[1383],{"type":69,"tag":186,"props":1384,"children":1385},{},[1386],{"type":75,"value":1387},"# Prepare and run\n",{"type":69,"tag":186,"props":1389,"children":1391},{"class":188,"line":1390},27,[1392],{"type":69,"tag":186,"props":1393,"children":1394},{},[1395],{"type":75,"value":1396},"mofa \u003C- prepare_mofa(\n",{"type":69,"tag":186,"props":1398,"children":1400},{"class":188,"line":1399},28,[1401],{"type":69,"tag":186,"props":1402,"children":1403},{},[1404],{"type":75,"value":1405},"  mofa,\n",{"type":69,"tag":186,"props":1407,"children":1409},{"class":188,"line":1408},29,[1410],{"type":69,"tag":186,"props":1411,"children":1412},{},[1413],{"type":75,"value":1414},"  data_options = data_opts,\n",{"type":69,"tag":186,"props":1416,"children":1418},{"class":188,"line":1417},30,[1419],{"type":69,"tag":186,"props":1420,"children":1421},{},[1422],{"type":75,"value":1423},"  model_options = model_opts,\n",{"type":69,"tag":186,"props":1425,"children":1427},{"class":188,"line":1426},31,[1428],{"type":69,"tag":186,"props":1429,"children":1430},{},[1431],{"type":75,"value":1432},"  training_options = train_opts\n",{"type":69,"tag":186,"props":1434,"children":1436},{"class":188,"line":1435},32,[1437],{"type":69,"tag":186,"props":1438,"children":1439},{},[1440],{"type":75,"value":328},{"type":69,"tag":186,"props":1442,"children":1444},{"class":188,"line":1443},33,[1445],{"type":69,"tag":186,"props":1446,"children":1447},{"emptyLinePlaceholder":211},[1448],{"type":75,"value":214},{"type":69,"tag":186,"props":1450,"children":1452},{"class":188,"line":1451},34,[1453],{"type":69,"tag":186,"props":1454,"children":1455},{},[1456],{"type":75,"value":1457},"mofa \u003C- run_mofa(mofa, outfile = \"mofa_model.hdf5\")\n",{"type":69,"tag":186,"props":1459,"children":1461},{"class":188,"line":1460},35,[1462],{"type":69,"tag":186,"props":1463,"children":1464},{"emptyLinePlaceholder":211},[1465],{"type":75,"value":214},{"type":69,"tag":186,"props":1467,"children":1469},{"class":188,"line":1468},36,[1470],{"type":69,"tag":186,"props":1471,"children":1472},{},[1473],{"type":75,"value":1474},"# Inspect variance explained per factor per view\n",{"type":69,"tag":186,"props":1476,"children":1478},{"class":188,"line":1477},37,[1479],{"type":69,"tag":186,"props":1480,"children":1481},{},[1482],{"type":75,"value":1483},"plot_variance_explained(mofa)\n",{"type":69,"tag":186,"props":1485,"children":1487},{"class":188,"line":1486},38,[1488],{"type":69,"tag":186,"props":1489,"children":1490},{"emptyLinePlaceholder":211},[1491],{"type":75,"value":214},{"type":69,"tag":186,"props":1493,"children":1495},{"class":188,"line":1494},39,[1496],{"type":69,"tag":186,"props":1497,"children":1498},{},[1499],{"type":75,"value":1500},"# Extract top features for factor 1\n",{"type":69,"tag":186,"props":1502,"children":1504},{"class":188,"line":1503},40,[1505],{"type":69,"tag":186,"props":1506,"children":1507},{},[1508],{"type":75,"value":1509},"weights \u003C- get_weights(mofa, views = \"transcriptomics\", factors = 1, as.data.frame = TRUE)\n",{"type":69,"tag":186,"props":1511,"children":1513},{"class":188,"line":1512},41,[1514],{"type":69,"tag":186,"props":1515,"children":1516},{},[1517],{"type":75,"value":1518},"top_genes \u003C- weights[order(abs(weights$value), decreasing = TRUE), ][1:50, ]\n",{"type":69,"tag":167,"props":1520,"children":1522},{"id":1521},"_3b-python-mofapy2",[1523],{"type":75,"value":1524},"3b. Python — mofapy2",{"type":69,"tag":174,"props":1526,"children":1528},{"className":176,"code":1527,"language":178,"meta":179,"style":179},"from mofapy2.run.entry_point import entry_point\nimport numpy as np\n\n# Prepare data: list of numpy arrays [views][groups]\n# Each array: samples x features\ndata = [\n    [expr_array],   # view 0: transcriptomics, group 0\n    [prot_array],   # view 1: proteomics, group 0\n    [meth_array],   # view 2: methylation, group 0\n]\n\nent = entry_point()\nent.set_data_options(scale_groups=False, scale_views=True)\nent.set_data_matrix(data, views_names=[\"transcriptomics\", \"proteomics\", \"methylation\"])\n\nent.set_model_options(factors=20, spikeslab_weights=True, ard_factors=True)\nent.set_train_options(iter=1000, convergence_mode=\"slow\", seed=42)\n\nent.build()\nent.run()\nent.save(\"mofa_model.hdf5\")\n",[1529],{"type":69,"tag":182,"props":1530,"children":1531},{"__ignoreMap":179},[1532,1540,1547,1554,1562,1570,1578,1586,1594,1602,1610,1617,1625,1633,1641,1648,1656,1664,1671,1679,1687],{"type":69,"tag":186,"props":1533,"children":1534},{"class":188,"line":189},[1535],{"type":69,"tag":186,"props":1536,"children":1537},{},[1538],{"type":75,"value":1539},"from mofapy2.run.entry_point import entry_point\n",{"type":69,"tag":186,"props":1541,"children":1542},{"class":188,"line":198},[1543],{"type":69,"tag":186,"props":1544,"children":1545},{},[1546],{"type":75,"value":709},{"type":69,"tag":186,"props":1548,"children":1549},{"class":188,"line":207},[1550],{"type":69,"tag":186,"props":1551,"children":1552},{"emptyLinePlaceholder":211},[1553],{"type":75,"value":214},{"type":69,"tag":186,"props":1555,"children":1556},{"class":188,"line":26},[1557],{"type":69,"tag":186,"props":1558,"children":1559},{},[1560],{"type":75,"value":1561},"# Prepare data: list of numpy arrays [views][groups]\n",{"type":69,"tag":186,"props":1563,"children":1564},{"class":188,"line":225},[1565],{"type":69,"tag":186,"props":1566,"children":1567},{},[1568],{"type":75,"value":1569},"# Each array: samples x features\n",{"type":69,"tag":186,"props":1571,"children":1572},{"class":188,"line":233},[1573],{"type":69,"tag":186,"props":1574,"children":1575},{},[1576],{"type":75,"value":1577},"data = [\n",{"type":69,"tag":186,"props":1579,"children":1580},{"class":188,"line":242},[1581],{"type":69,"tag":186,"props":1582,"children":1583},{},[1584],{"type":75,"value":1585},"    [expr_array],   # view 0: transcriptomics, group 0\n",{"type":69,"tag":186,"props":1587,"children":1588},{"class":188,"line":251},[1589],{"type":69,"tag":186,"props":1590,"children":1591},{},[1592],{"type":75,"value":1593},"    [prot_array],   # view 1: proteomics, group 0\n",{"type":69,"tag":186,"props":1595,"children":1596},{"class":188,"line":259},[1597],{"type":69,"tag":186,"props":1598,"children":1599},{},[1600],{"type":75,"value":1601},"    [meth_array],   # view 2: methylation, group 0\n",{"type":69,"tag":186,"props":1603,"children":1604},{"class":188,"line":268},[1605],{"type":69,"tag":186,"props":1606,"children":1607},{},[1608],{"type":75,"value":1609},"]\n",{"type":69,"tag":186,"props":1611,"children":1612},{"class":188,"line":277},[1613],{"type":69,"tag":186,"props":1614,"children":1615},{"emptyLinePlaceholder":211},[1616],{"type":75,"value":214},{"type":69,"tag":186,"props":1618,"children":1619},{"class":188,"line":286},[1620],{"type":69,"tag":186,"props":1621,"children":1622},{},[1623],{"type":75,"value":1624},"ent = entry_point()\n",{"type":69,"tag":186,"props":1626,"children":1627},{"class":188,"line":295},[1628],{"type":69,"tag":186,"props":1629,"children":1630},{},[1631],{"type":75,"value":1632},"ent.set_data_options(scale_groups=False, scale_views=True)\n",{"type":69,"tag":186,"props":1634,"children":1635},{"class":188,"line":304},[1636],{"type":69,"tag":186,"props":1637,"children":1638},{},[1639],{"type":75,"value":1640},"ent.set_data_matrix(data, views_names=[\"transcriptomics\", \"proteomics\", \"methylation\"])\n",{"type":69,"tag":186,"props":1642,"children":1643},{"class":188,"line":313},[1644],{"type":69,"tag":186,"props":1645,"children":1646},{"emptyLinePlaceholder":211},[1647],{"type":75,"value":214},{"type":69,"tag":186,"props":1649,"children":1650},{"class":188,"line":322},[1651],{"type":69,"tag":186,"props":1652,"children":1653},{},[1654],{"type":75,"value":1655},"ent.set_model_options(factors=20, spikeslab_weights=True, ard_factors=True)\n",{"type":69,"tag":186,"props":1657,"children":1658},{"class":188,"line":331},[1659],{"type":69,"tag":186,"props":1660,"children":1661},{},[1662],{"type":75,"value":1663},"ent.set_train_options(iter=1000, convergence_mode=\"slow\", seed=42)\n",{"type":69,"tag":186,"props":1665,"children":1666},{"class":188,"line":339},[1667],{"type":69,"tag":186,"props":1668,"children":1669},{"emptyLinePlaceholder":211},[1670],{"type":75,"value":214},{"type":69,"tag":186,"props":1672,"children":1673},{"class":188,"line":348},[1674],{"type":69,"tag":186,"props":1675,"children":1676},{},[1677],{"type":75,"value":1678},"ent.build()\n",{"type":69,"tag":186,"props":1680,"children":1681},{"class":188,"line":357},[1682],{"type":69,"tag":186,"props":1683,"children":1684},{},[1685],{"type":75,"value":1686},"ent.run()\n",{"type":69,"tag":186,"props":1688,"children":1689},{"class":188,"line":366},[1690],{"type":69,"tag":186,"props":1691,"children":1692},{},[1693],{"type":75,"value":1694},"ent.save(\"mofa_model.hdf5\")\n",{"type":69,"tag":167,"props":1696,"children":1698},{"id":1697},"mofa-parameter-table",[1699],{"type":75,"value":1700},"MOFA Parameter Table",{"type":69,"tag":537,"props":1702,"children":1703},{},[1704,1724],{"type":69,"tag":541,"props":1705,"children":1706},{},[1707],{"type":69,"tag":545,"props":1708,"children":1709},{},[1710,1714,1719],{"type":69,"tag":549,"props":1711,"children":1712},{},[1713],{"type":75,"value":553},{"type":69,"tag":549,"props":1715,"children":1716},{},[1717],{"type":75,"value":1718},"Default",{"type":69,"tag":549,"props":1720,"children":1721},{},[1722],{"type":75,"value":1723},"Guidance",{"type":69,"tag":565,"props":1725,"children":1726},{},[1727,1757,1798,1831,1862,1893],{"type":69,"tag":545,"props":1728,"children":1729},{},[1730,1747,1752],{"type":69,"tag":572,"props":1731,"children":1732},{},[1733,1739,1741],{"type":69,"tag":182,"props":1734,"children":1736},{"className":1735},[],[1737],{"type":75,"value":1738},"num_factors",{"type":75,"value":1740}," \u002F ",{"type":69,"tag":182,"props":1742,"children":1744},{"className":1743},[],[1745],{"type":75,"value":1746},"factors",{"type":69,"tag":572,"props":1748,"children":1749},{},[1750],{"type":75,"value":1751},"10",{"type":69,"tag":572,"props":1753,"children":1754},{},[1755],{"type":75,"value":1756},"Set 15–25 for exploratory analysis; inactive factors auto-pruned",{"type":69,"tag":545,"props":1758,"children":1759},{},[1760,1769,1778],{"type":69,"tag":572,"props":1761,"children":1762},{},[1763],{"type":69,"tag":182,"props":1764,"children":1766},{"className":1765},[],[1767],{"type":75,"value":1768},"convergence_mode",{"type":69,"tag":572,"props":1770,"children":1771},{},[1772],{"type":69,"tag":182,"props":1773,"children":1775},{"className":1774},[],[1776],{"type":75,"value":1777},"\"fast\"",{"type":69,"tag":572,"props":1779,"children":1780},{},[1781,1783,1789,1791,1796],{"type":75,"value":1782},"Use ",{"type":69,"tag":182,"props":1784,"children":1786},{"className":1785},[],[1787],{"type":75,"value":1788},"\"slow\"",{"type":75,"value":1790}," for final analysis; ",{"type":69,"tag":182,"props":1792,"children":1794},{"className":1793},[],[1795],{"type":75,"value":1777},{"type":75,"value":1797}," for exploration",{"type":69,"tag":545,"props":1799,"children":1800},{},[1801,1810,1826],{"type":69,"tag":572,"props":1802,"children":1803},{},[1804],{"type":69,"tag":182,"props":1805,"children":1807},{"className":1806},[],[1808],{"type":75,"value":1809},"scale_views",{"type":69,"tag":572,"props":1811,"children":1812},{},[1813,1819,1820],{"type":69,"tag":182,"props":1814,"children":1816},{"className":1815},[],[1817],{"type":75,"value":1818},"TRUE",{"type":75,"value":1740},{"type":69,"tag":182,"props":1821,"children":1823},{"className":1822},[],[1824],{"type":75,"value":1825},"True",{"type":69,"tag":572,"props":1827,"children":1828},{},[1829],{"type":75,"value":1830},"MUST be True to equalize variance across views",{"type":69,"tag":545,"props":1832,"children":1833},{},[1834,1843,1857],{"type":69,"tag":572,"props":1835,"children":1836},{},[1837],{"type":69,"tag":182,"props":1838,"children":1840},{"className":1839},[],[1841],{"type":75,"value":1842},"spikeslab_weights",{"type":69,"tag":572,"props":1844,"children":1845},{},[1846,1851,1852],{"type":69,"tag":182,"props":1847,"children":1849},{"className":1848},[],[1850],{"type":75,"value":1818},{"type":75,"value":1740},{"type":69,"tag":182,"props":1853,"children":1855},{"className":1854},[],[1856],{"type":75,"value":1825},{"type":69,"tag":572,"props":1858,"children":1859},{},[1860],{"type":75,"value":1861},"Enables sparse feature selection per factor",{"type":69,"tag":545,"props":1863,"children":1864},{},[1865,1874,1888],{"type":69,"tag":572,"props":1866,"children":1867},{},[1868],{"type":69,"tag":182,"props":1869,"children":1871},{"className":1870},[],[1872],{"type":75,"value":1873},"ard_factors",{"type":69,"tag":572,"props":1875,"children":1876},{},[1877,1882,1883],{"type":69,"tag":182,"props":1878,"children":1880},{"className":1879},[],[1881],{"type":75,"value":1818},{"type":75,"value":1740},{"type":69,"tag":182,"props":1884,"children":1886},{"className":1885},[],[1887],{"type":75,"value":1825},{"type":69,"tag":572,"props":1889,"children":1890},{},[1891],{"type":75,"value":1892},"Automatic relevance determination; prunes inactive factors",{"type":69,"tag":545,"props":1894,"children":1895},{},[1896,1905,1910],{"type":69,"tag":572,"props":1897,"children":1898},{},[1899],{"type":69,"tag":182,"props":1900,"children":1902},{"className":1901},[],[1903],{"type":75,"value":1904},"seed",{"type":69,"tag":572,"props":1906,"children":1907},{},[1908],{"type":75,"value":1909},"None",{"type":69,"tag":572,"props":1911,"children":1912},{},[1913],{"type":75,"value":1914},"ALWAYS set for reproducibility",{"type":69,"tag":123,"props":1916,"children":1917},{},[],{"type":69,"tag":78,"props":1919,"children":1921},{"id":1920},"_4-gsea-enrichment",[1922],{"type":75,"value":1923},"4. GSEA Enrichment",{"type":69,"tag":167,"props":1925,"children":1927},{"id":1926},"_4a-python-gseapy",[1928],{"type":75,"value":1929},"4a. Python — gseapy",{"type":69,"tag":174,"props":1931,"children":1933},{"className":176,"code":1932,"language":178,"meta":179,"style":179},"import gseapy as gp\nimport pandas as pd\n\n# ranked_genes: DataFrame with columns [\"gene\", \"rank_metric\"]\n# rank_metric can be: log2FC, -log10(p) * sign(FC), or MOFA weight\nranked_genes = pd.read_csv(\"ranked_genes.csv\")\n\n# Pre-ranked GSEA against MSigDB Hallmark gene sets\nresult = gp.prerank(\n    rnk=ranked_genes,\n    gene_sets=\"MSigDB_Hallmark_2020\",\n    min_size=15,\n    max_size=500,\n    permutation_num=1000,\n    seed=42,\n    outdir=\"gsea_results\",\n)\n\n# Filter significant results\nsig = result.res2d[result.res2d[\"FDR q-val\"] \u003C 0.05]\nprint(sig[[\"Term\", \"NES\", \"FDR q-val\"]].sort_values(\"NES\", ascending=False))\n",[1934],{"type":69,"tag":182,"props":1935,"children":1936},{"__ignoreMap":179},[1937,1945,1952,1959,1967,1975,1983,1990,1998,2006,2014,2022,2030,2038,2046,2054,2062,2069,2076,2084,2092],{"type":69,"tag":186,"props":1938,"children":1939},{"class":188,"line":189},[1940],{"type":69,"tag":186,"props":1941,"children":1942},{},[1943],{"type":75,"value":1944},"import gseapy as gp\n",{"type":69,"tag":186,"props":1946,"children":1947},{"class":188,"line":198},[1948],{"type":69,"tag":186,"props":1949,"children":1950},{},[1951],{"type":75,"value":195},{"type":69,"tag":186,"props":1953,"children":1954},{"class":188,"line":207},[1955],{"type":69,"tag":186,"props":1956,"children":1957},{"emptyLinePlaceholder":211},[1958],{"type":75,"value":214},{"type":69,"tag":186,"props":1960,"children":1961},{"class":188,"line":26},[1962],{"type":69,"tag":186,"props":1963,"children":1964},{},[1965],{"type":75,"value":1966},"# ranked_genes: DataFrame with columns [\"gene\", \"rank_metric\"]\n",{"type":69,"tag":186,"props":1968,"children":1969},{"class":188,"line":225},[1970],{"type":69,"tag":186,"props":1971,"children":1972},{},[1973],{"type":75,"value":1974},"# rank_metric can be: log2FC, -log10(p) * sign(FC), or MOFA weight\n",{"type":69,"tag":186,"props":1976,"children":1977},{"class":188,"line":233},[1978],{"type":69,"tag":186,"props":1979,"children":1980},{},[1981],{"type":75,"value":1982},"ranked_genes = pd.read_csv(\"ranked_genes.csv\")\n",{"type":69,"tag":186,"props":1984,"children":1985},{"class":188,"line":242},[1986],{"type":69,"tag":186,"props":1987,"children":1988},{"emptyLinePlaceholder":211},[1989],{"type":75,"value":214},{"type":69,"tag":186,"props":1991,"children":1992},{"class":188,"line":251},[1993],{"type":69,"tag":186,"props":1994,"children":1995},{},[1996],{"type":75,"value":1997},"# Pre-ranked GSEA against MSigDB Hallmark gene sets\n",{"type":69,"tag":186,"props":1999,"children":2000},{"class":188,"line":259},[2001],{"type":69,"tag":186,"props":2002,"children":2003},{},[2004],{"type":75,"value":2005},"result = gp.prerank(\n",{"type":69,"tag":186,"props":2007,"children":2008},{"class":188,"line":268},[2009],{"type":69,"tag":186,"props":2010,"children":2011},{},[2012],{"type":75,"value":2013},"    rnk=ranked_genes,\n",{"type":69,"tag":186,"props":2015,"children":2016},{"class":188,"line":277},[2017],{"type":69,"tag":186,"props":2018,"children":2019},{},[2020],{"type":75,"value":2021},"    gene_sets=\"MSigDB_Hallmark_2020\",\n",{"type":69,"tag":186,"props":2023,"children":2024},{"class":188,"line":286},[2025],{"type":69,"tag":186,"props":2026,"children":2027},{},[2028],{"type":75,"value":2029},"    min_size=15,\n",{"type":69,"tag":186,"props":2031,"children":2032},{"class":188,"line":295},[2033],{"type":69,"tag":186,"props":2034,"children":2035},{},[2036],{"type":75,"value":2037},"    max_size=500,\n",{"type":69,"tag":186,"props":2039,"children":2040},{"class":188,"line":304},[2041],{"type":69,"tag":186,"props":2042,"children":2043},{},[2044],{"type":75,"value":2045},"    permutation_num=1000,\n",{"type":69,"tag":186,"props":2047,"children":2048},{"class":188,"line":313},[2049],{"type":69,"tag":186,"props":2050,"children":2051},{},[2052],{"type":75,"value":2053},"    seed=42,\n",{"type":69,"tag":186,"props":2055,"children":2056},{"class":188,"line":322},[2057],{"type":69,"tag":186,"props":2058,"children":2059},{},[2060],{"type":75,"value":2061},"    outdir=\"gsea_results\",\n",{"type":69,"tag":186,"props":2063,"children":2064},{"class":188,"line":331},[2065],{"type":69,"tag":186,"props":2066,"children":2067},{},[2068],{"type":75,"value":328},{"type":69,"tag":186,"props":2070,"children":2071},{"class":188,"line":339},[2072],{"type":69,"tag":186,"props":2073,"children":2074},{"emptyLinePlaceholder":211},[2075],{"type":75,"value":214},{"type":69,"tag":186,"props":2077,"children":2078},{"class":188,"line":348},[2079],{"type":69,"tag":186,"props":2080,"children":2081},{},[2082],{"type":75,"value":2083},"# Filter significant results\n",{"type":69,"tag":186,"props":2085,"children":2086},{"class":188,"line":357},[2087],{"type":69,"tag":186,"props":2088,"children":2089},{},[2090],{"type":75,"value":2091},"sig = result.res2d[result.res2d[\"FDR q-val\"] \u003C 0.05]\n",{"type":69,"tag":186,"props":2093,"children":2094},{"class":188,"line":366},[2095],{"type":69,"tag":186,"props":2096,"children":2097},{},[2098],{"type":75,"value":2099},"print(sig[[\"Term\", \"NES\", \"FDR q-val\"]].sort_values(\"NES\", ascending=False))\n",{"type":69,"tag":167,"props":2101,"children":2103},{"id":2102},"_4b-r-fgsea-with-clusterprofiler",[2104],{"type":75,"value":2105},"4b. R — fgsea with clusterProfiler",{"type":69,"tag":174,"props":2107,"children":2109},{"className":407,"code":2108,"language":409,"meta":179,"style":179},"library(fgsea)\nlibrary(msigdbr)\n\n# Get Hallmark gene sets for human\nhallmark \u003C- msigdbr(species = \"Homo sapiens\", category = \"H\")\npathways \u003C- split(hallmark$gene_symbol, hallmark$gs_name)\n\n# ranked_genes: named numeric vector (names = gene symbols, values = rank metric)\nranked_genes \u003C- setNames(de_results$log2FoldChange, de_results$gene_symbol)\nranked_genes \u003C- sort(ranked_genes, decreasing = TRUE)\n\n# Run fgsea\nfgsea_res \u003C- fgsea(\n  pathways = pathways,\n  stats = ranked_genes,\n  minSize = 15,\n  maxSize = 500,\n  nPermSimple = 10000\n)\n\n# Filter and sort\nsig_pathways \u003C- fgsea_res[fgsea_res$padj \u003C 0.05, ]\nsig_pathways \u003C- sig_pathways[order(sig_pathways$NES, decreasing = TRUE), ]\nprint(sig_pathways[, c(\"pathway\", \"NES\", \"padj\")])\n",[2110],{"type":69,"tag":182,"props":2111,"children":2112},{"__ignoreMap":179},[2113,2121,2129,2136,2144,2152,2160,2167,2175,2183,2191,2198,2206,2214,2222,2230,2238,2246,2254,2261,2268,2276,2284,2292],{"type":69,"tag":186,"props":2114,"children":2115},{"class":188,"line":189},[2116],{"type":69,"tag":186,"props":2117,"children":2118},{},[2119],{"type":75,"value":2120},"library(fgsea)\n",{"type":69,"tag":186,"props":2122,"children":2123},{"class":188,"line":198},[2124],{"type":69,"tag":186,"props":2125,"children":2126},{},[2127],{"type":75,"value":2128},"library(msigdbr)\n",{"type":69,"tag":186,"props":2130,"children":2131},{"class":188,"line":207},[2132],{"type":69,"tag":186,"props":2133,"children":2134},{"emptyLinePlaceholder":211},[2135],{"type":75,"value":214},{"type":69,"tag":186,"props":2137,"children":2138},{"class":188,"line":26},[2139],{"type":69,"tag":186,"props":2140,"children":2141},{},[2142],{"type":75,"value":2143},"# Get Hallmark gene sets for human\n",{"type":69,"tag":186,"props":2145,"children":2146},{"class":188,"line":225},[2147],{"type":69,"tag":186,"props":2148,"children":2149},{},[2150],{"type":75,"value":2151},"hallmark \u003C- msigdbr(species = \"Homo sapiens\", category = \"H\")\n",{"type":69,"tag":186,"props":2153,"children":2154},{"class":188,"line":233},[2155],{"type":69,"tag":186,"props":2156,"children":2157},{},[2158],{"type":75,"value":2159},"pathways \u003C- split(hallmark$gene_symbol, hallmark$gs_name)\n",{"type":69,"tag":186,"props":2161,"children":2162},{"class":188,"line":242},[2163],{"type":69,"tag":186,"props":2164,"children":2165},{"emptyLinePlaceholder":211},[2166],{"type":75,"value":214},{"type":69,"tag":186,"props":2168,"children":2169},{"class":188,"line":251},[2170],{"type":69,"tag":186,"props":2171,"children":2172},{},[2173],{"type":75,"value":2174},"# ranked_genes: named numeric vector (names = gene symbols, values = rank metric)\n",{"type":69,"tag":186,"props":2176,"children":2177},{"class":188,"line":259},[2178],{"type":69,"tag":186,"props":2179,"children":2180},{},[2181],{"type":75,"value":2182},"ranked_genes \u003C- setNames(de_results$log2FoldChange, de_results$gene_symbol)\n",{"type":69,"tag":186,"props":2184,"children":2185},{"class":188,"line":268},[2186],{"type":69,"tag":186,"props":2187,"children":2188},{},[2189],{"type":75,"value":2190},"ranked_genes \u003C- sort(ranked_genes, decreasing = TRUE)\n",{"type":69,"tag":186,"props":2192,"children":2193},{"class":188,"line":277},[2194],{"type":69,"tag":186,"props":2195,"children":2196},{"emptyLinePlaceholder":211},[2197],{"type":75,"value":214},{"type":69,"tag":186,"props":2199,"children":2200},{"class":188,"line":286},[2201],{"type":69,"tag":186,"props":2202,"children":2203},{},[2204],{"type":75,"value":2205},"# Run fgsea\n",{"type":69,"tag":186,"props":2207,"children":2208},{"class":188,"line":295},[2209],{"type":69,"tag":186,"props":2210,"children":2211},{},[2212],{"type":75,"value":2213},"fgsea_res \u003C- fgsea(\n",{"type":69,"tag":186,"props":2215,"children":2216},{"class":188,"line":304},[2217],{"type":69,"tag":186,"props":2218,"children":2219},{},[2220],{"type":75,"value":2221},"  pathways = pathways,\n",{"type":69,"tag":186,"props":2223,"children":2224},{"class":188,"line":313},[2225],{"type":69,"tag":186,"props":2226,"children":2227},{},[2228],{"type":75,"value":2229},"  stats = ranked_genes,\n",{"type":69,"tag":186,"props":2231,"children":2232},{"class":188,"line":322},[2233],{"type":69,"tag":186,"props":2234,"children":2235},{},[2236],{"type":75,"value":2237},"  minSize = 15,\n",{"type":69,"tag":186,"props":2239,"children":2240},{"class":188,"line":331},[2241],{"type":69,"tag":186,"props":2242,"children":2243},{},[2244],{"type":75,"value":2245},"  maxSize = 500,\n",{"type":69,"tag":186,"props":2247,"children":2248},{"class":188,"line":339},[2249],{"type":69,"tag":186,"props":2250,"children":2251},{},[2252],{"type":75,"value":2253},"  nPermSimple = 10000\n",{"type":69,"tag":186,"props":2255,"children":2256},{"class":188,"line":348},[2257],{"type":69,"tag":186,"props":2258,"children":2259},{},[2260],{"type":75,"value":328},{"type":69,"tag":186,"props":2262,"children":2263},{"class":188,"line":357},[2264],{"type":69,"tag":186,"props":2265,"children":2266},{"emptyLinePlaceholder":211},[2267],{"type":75,"value":214},{"type":69,"tag":186,"props":2269,"children":2270},{"class":188,"line":366},[2271],{"type":69,"tag":186,"props":2272,"children":2273},{},[2274],{"type":75,"value":2275},"# Filter and sort\n",{"type":69,"tag":186,"props":2277,"children":2278},{"class":188,"line":375},[2279],{"type":69,"tag":186,"props":2280,"children":2281},{},[2282],{"type":75,"value":2283},"sig_pathways \u003C- fgsea_res[fgsea_res$padj \u003C 0.05, ]\n",{"type":69,"tag":186,"props":2285,"children":2286},{"class":188,"line":384},[2287],{"type":69,"tag":186,"props":2288,"children":2289},{},[2290],{"type":75,"value":2291},"sig_pathways \u003C- sig_pathways[order(sig_pathways$NES, decreasing = TRUE), ]\n",{"type":69,"tag":186,"props":2293,"children":2294},{"class":188,"line":392},[2295],{"type":69,"tag":186,"props":2296,"children":2297},{},[2298],{"type":75,"value":2299},"print(sig_pathways[, c(\"pathway\", \"NES\", \"padj\")])\n",{"type":69,"tag":167,"props":2301,"children":2303},{"id":2302},"enrichment-parameter-table",[2304],{"type":75,"value":2305},"Enrichment Parameter Table",{"type":69,"tag":537,"props":2307,"children":2308},{},[2309,2329],{"type":69,"tag":541,"props":2310,"children":2311},{},[2312],{"type":69,"tag":545,"props":2313,"children":2314},{},[2315,2319,2324],{"type":69,"tag":549,"props":2316,"children":2317},{},[2318],{"type":75,"value":553},{"type":69,"tag":549,"props":2320,"children":2321},{},[2322],{"type":75,"value":2323},"gseapy (Python)",{"type":69,"tag":549,"props":2325,"children":2326},{},[2327],{"type":75,"value":2328},"fgsea (R)",{"type":69,"tag":565,"props":2330,"children":2331},{},[2332,2368,2394,2420,2446,2472],{"type":69,"tag":545,"props":2333,"children":2334},{},[2335,2340,2351],{"type":69,"tag":572,"props":2336,"children":2337},{},[2338],{"type":75,"value":2339},"Gene set source",{"type":69,"tag":572,"props":2341,"children":2342},{},[2343,2349],{"type":69,"tag":182,"props":2344,"children":2346},{"className":2345},[],[2347],{"type":75,"value":2348},"\"MSigDB_Hallmark_2020\"",{"type":75,"value":2350}," or GMT file",{"type":69,"tag":572,"props":2352,"children":2353},{},[2354,2360,2362],{"type":69,"tag":182,"props":2355,"children":2357},{"className":2356},[],[2358],{"type":75,"value":2359},"msigdbr()",{"type":75,"value":2361}," + ",{"type":69,"tag":182,"props":2363,"children":2365},{"className":2364},[],[2366],{"type":75,"value":2367},"split()",{"type":69,"tag":545,"props":2369,"children":2370},{},[2371,2376,2385],{"type":69,"tag":572,"props":2372,"children":2373},{},[2374],{"type":75,"value":2375},"Min gene set size",{"type":69,"tag":572,"props":2377,"children":2378},{},[2379],{"type":69,"tag":182,"props":2380,"children":2382},{"className":2381},[],[2383],{"type":75,"value":2384},"min_size=15",{"type":69,"tag":572,"props":2386,"children":2387},{},[2388],{"type":69,"tag":182,"props":2389,"children":2391},{"className":2390},[],[2392],{"type":75,"value":2393},"minSize = 15",{"type":69,"tag":545,"props":2395,"children":2396},{},[2397,2402,2411],{"type":69,"tag":572,"props":2398,"children":2399},{},[2400],{"type":75,"value":2401},"Max gene set size",{"type":69,"tag":572,"props":2403,"children":2404},{},[2405],{"type":69,"tag":182,"props":2406,"children":2408},{"className":2407},[],[2409],{"type":75,"value":2410},"max_size=500",{"type":69,"tag":572,"props":2412,"children":2413},{},[2414],{"type":69,"tag":182,"props":2415,"children":2417},{"className":2416},[],[2418],{"type":75,"value":2419},"maxSize = 500",{"type":69,"tag":545,"props":2421,"children":2422},{},[2423,2428,2437],{"type":69,"tag":572,"props":2424,"children":2425},{},[2426],{"type":75,"value":2427},"Permutations",{"type":69,"tag":572,"props":2429,"children":2430},{},[2431],{"type":69,"tag":182,"props":2432,"children":2434},{"className":2433},[],[2435],{"type":75,"value":2436},"permutation_num=1000",{"type":69,"tag":572,"props":2438,"children":2439},{},[2440],{"type":69,"tag":182,"props":2441,"children":2443},{"className":2442},[],[2444],{"type":75,"value":2445},"nPermSimple = 10000",{"type":69,"tag":545,"props":2447,"children":2448},{},[2449,2454,2463],{"type":69,"tag":572,"props":2450,"children":2451},{},[2452],{"type":75,"value":2453},"Significance threshold",{"type":69,"tag":572,"props":2455,"children":2456},{},[2457],{"type":69,"tag":182,"props":2458,"children":2460},{"className":2459},[],[2461],{"type":75,"value":2462},"FDR q-val \u003C 0.05",{"type":69,"tag":572,"props":2464,"children":2465},{},[2466],{"type":69,"tag":182,"props":2467,"children":2469},{"className":2468},[],[2470],{"type":75,"value":2471},"padj \u003C 0.05",{"type":69,"tag":545,"props":2473,"children":2474},{},[2475,2480,2485],{"type":69,"tag":572,"props":2476,"children":2477},{},[2478],{"type":75,"value":2479},"Rank metric",{"type":69,"tag":572,"props":2481,"children":2482},{},[2483],{"type":75,"value":2484},"log2FC, signed -log10(p), or MOFA weight",{"type":69,"tag":572,"props":2486,"children":2487},{},[2488],{"type":75,"value":2489},"Same",{"type":69,"tag":123,"props":2491,"children":2492},{},[],{"type":69,"tag":78,"props":2494,"children":2496},{"id":2495},"_5-consensus-clustering",[2497],{"type":75,"value":2498},"5. Consensus Clustering",{"type":69,"tag":167,"props":2500,"children":2502},{"id":2501},"python-scikit-learn-based-consensus",[2503],{"type":75,"value":2504},"Python — scikit-learn based consensus",{"type":69,"tag":174,"props":2506,"children":2508},{"className":176,"code":2507,"language":178,"meta":179,"style":179},"import numpy as np\nfrom sklearn.cluster import KMeans\nfrom sklearn.metrics import silhouette_score\n\ndef consensus_clustering(data, k_range=range(2, 9), n_iterations=100, seed=42):\n    \"\"\"Run consensus clustering over a range of k values.\n    data: samples x features array. Returns dict mapping k to results.\n    \"\"\"\n    rng = np.random.default_rng(seed)\n    n_samples = data.shape[0]\n    results = {}\n\n    for k in k_range:\n        co_occurrence = np.zeros((n_samples, n_samples))\n        co_sampled = np.zeros((n_samples, n_samples))\n\n        for _ in range(n_iterations):\n            # Subsample 80% of samples\n            idx = rng.choice(n_samples, size=int(0.8 * n_samples), replace=False)\n            km = KMeans(n_clusters=k, n_init=10, random_state=rng.integers(1e6))\n            labels = km.fit_predict(data[idx])\n\n            for i in range(len(idx)):\n                for j in range(i + 1, len(idx)):\n                    co_sampled[idx[i], idx[j]] += 1\n                    co_sampled[idx[j], idx[i]] += 1\n                    if labels[i] == labels[j]:\n                        co_occurrence[idx[i], idx[j]] += 1\n                        co_occurrence[idx[j], idx[i]] += 1\n\n        # Consensus matrix\n        with np.errstate(divide=\"ignore\", invalid=\"ignore\"):\n            consensus = np.where(co_sampled > 0, co_occurrence \u002F co_sampled, 0)\n\n        # Final clustering on consensus matrix\n        km_final = KMeans(n_clusters=k, n_init=10, random_state=seed)\n        final_labels = km_final.fit_predict(1 - consensus)  # distance = 1 - consensus\n        sil = silhouette_score(1 - consensus, final_labels, metric=\"precomputed\")\n\n        results[k] = {\"consensus_matrix\": consensus, \"silhouette\": sil, \"labels\": final_labels}\n        print(f\"k={k}: silhouette={sil:.3f}\")\n\n    return results\n\n# Usage with MOFA factors\n# factors: samples x factors array from MOFA\nresults = consensus_clustering(factors, k_range=range(2, 9))\n\n# Select optimal k by maximum silhouette score\noptimal_k = max(results, key=lambda k: results[k][\"silhouette\"])\nprint(f\"Optimal k: {optimal_k}\")\n",[2509],{"type":69,"tag":182,"props":2510,"children":2511},{"__ignoreMap":179},[2512,2519,2527,2535,2542,2550,2558,2566,2574,2582,2590,2598,2605,2613,2621,2629,2636,2644,2652,2660,2668,2676,2683,2691,2699,2707,2715,2723,2731,2739,2746,2754,2762,2770,2777,2785,2793,2801,2809,2816,2824,2832,2840,2849,2857,2866,2875,2884,2892,2901,2910],{"type":69,"tag":186,"props":2513,"children":2514},{"class":188,"line":189},[2515],{"type":69,"tag":186,"props":2516,"children":2517},{},[2518],{"type":75,"value":709},{"type":69,"tag":186,"props":2520,"children":2521},{"class":188,"line":198},[2522],{"type":69,"tag":186,"props":2523,"children":2524},{},[2525],{"type":75,"value":2526},"from sklearn.cluster import KMeans\n",{"type":69,"tag":186,"props":2528,"children":2529},{"class":188,"line":207},[2530],{"type":69,"tag":186,"props":2531,"children":2532},{},[2533],{"type":75,"value":2534},"from sklearn.metrics import silhouette_score\n",{"type":69,"tag":186,"props":2536,"children":2537},{"class":188,"line":26},[2538],{"type":69,"tag":186,"props":2539,"children":2540},{"emptyLinePlaceholder":211},[2541],{"type":75,"value":214},{"type":69,"tag":186,"props":2543,"children":2544},{"class":188,"line":225},[2545],{"type":69,"tag":186,"props":2546,"children":2547},{},[2548],{"type":75,"value":2549},"def consensus_clustering(data, k_range=range(2, 9), n_iterations=100, seed=42):\n",{"type":69,"tag":186,"props":2551,"children":2552},{"class":188,"line":233},[2553],{"type":69,"tag":186,"props":2554,"children":2555},{},[2556],{"type":75,"value":2557},"    \"\"\"Run consensus clustering over a range of k values.\n",{"type":69,"tag":186,"props":2559,"children":2560},{"class":188,"line":242},[2561],{"type":69,"tag":186,"props":2562,"children":2563},{},[2564],{"type":75,"value":2565},"    data: samples x features array. Returns dict mapping k to results.\n",{"type":69,"tag":186,"props":2567,"children":2568},{"class":188,"line":251},[2569],{"type":69,"tag":186,"props":2570,"children":2571},{},[2572],{"type":75,"value":2573},"    \"\"\"\n",{"type":69,"tag":186,"props":2575,"children":2576},{"class":188,"line":259},[2577],{"type":69,"tag":186,"props":2578,"children":2579},{},[2580],{"type":75,"value":2581},"    rng = np.random.default_rng(seed)\n",{"type":69,"tag":186,"props":2583,"children":2584},{"class":188,"line":268},[2585],{"type":69,"tag":186,"props":2586,"children":2587},{},[2588],{"type":75,"value":2589},"    n_samples = data.shape[0]\n",{"type":69,"tag":186,"props":2591,"children":2592},{"class":188,"line":277},[2593],{"type":69,"tag":186,"props":2594,"children":2595},{},[2596],{"type":75,"value":2597},"    results = {}\n",{"type":69,"tag":186,"props":2599,"children":2600},{"class":188,"line":286},[2601],{"type":69,"tag":186,"props":2602,"children":2603},{"emptyLinePlaceholder":211},[2604],{"type":75,"value":214},{"type":69,"tag":186,"props":2606,"children":2607},{"class":188,"line":295},[2608],{"type":69,"tag":186,"props":2609,"children":2610},{},[2611],{"type":75,"value":2612},"    for k in k_range:\n",{"type":69,"tag":186,"props":2614,"children":2615},{"class":188,"line":304},[2616],{"type":69,"tag":186,"props":2617,"children":2618},{},[2619],{"type":75,"value":2620},"        co_occurrence = np.zeros((n_samples, n_samples))\n",{"type":69,"tag":186,"props":2622,"children":2623},{"class":188,"line":313},[2624],{"type":69,"tag":186,"props":2625,"children":2626},{},[2627],{"type":75,"value":2628},"        co_sampled = np.zeros((n_samples, n_samples))\n",{"type":69,"tag":186,"props":2630,"children":2631},{"class":188,"line":322},[2632],{"type":69,"tag":186,"props":2633,"children":2634},{"emptyLinePlaceholder":211},[2635],{"type":75,"value":214},{"type":69,"tag":186,"props":2637,"children":2638},{"class":188,"line":331},[2639],{"type":69,"tag":186,"props":2640,"children":2641},{},[2642],{"type":75,"value":2643},"        for _ in range(n_iterations):\n",{"type":69,"tag":186,"props":2645,"children":2646},{"class":188,"line":339},[2647],{"type":69,"tag":186,"props":2648,"children":2649},{},[2650],{"type":75,"value":2651},"            # Subsample 80% of samples\n",{"type":69,"tag":186,"props":2653,"children":2654},{"class":188,"line":348},[2655],{"type":69,"tag":186,"props":2656,"children":2657},{},[2658],{"type":75,"value":2659},"            idx = rng.choice(n_samples, size=int(0.8 * n_samples), replace=False)\n",{"type":69,"tag":186,"props":2661,"children":2662},{"class":188,"line":357},[2663],{"type":69,"tag":186,"props":2664,"children":2665},{},[2666],{"type":75,"value":2667},"            km = KMeans(n_clusters=k, n_init=10, random_state=rng.integers(1e6))\n",{"type":69,"tag":186,"props":2669,"children":2670},{"class":188,"line":366},[2671],{"type":69,"tag":186,"props":2672,"children":2673},{},[2674],{"type":75,"value":2675},"            labels = km.fit_predict(data[idx])\n",{"type":69,"tag":186,"props":2677,"children":2678},{"class":188,"line":375},[2679],{"type":69,"tag":186,"props":2680,"children":2681},{"emptyLinePlaceholder":211},[2682],{"type":75,"value":214},{"type":69,"tag":186,"props":2684,"children":2685},{"class":188,"line":384},[2686],{"type":69,"tag":186,"props":2687,"children":2688},{},[2689],{"type":75,"value":2690},"            for i in range(len(idx)):\n",{"type":69,"tag":186,"props":2692,"children":2693},{"class":188,"line":392},[2694],{"type":69,"tag":186,"props":2695,"children":2696},{},[2697],{"type":75,"value":2698},"                for j in range(i + 1, len(idx)):\n",{"type":69,"tag":186,"props":2700,"children":2701},{"class":188,"line":1373},[2702],{"type":69,"tag":186,"props":2703,"children":2704},{},[2705],{"type":75,"value":2706},"                    co_sampled[idx[i], idx[j]] += 1\n",{"type":69,"tag":186,"props":2708,"children":2709},{"class":188,"line":1381},[2710],{"type":69,"tag":186,"props":2711,"children":2712},{},[2713],{"type":75,"value":2714},"                    co_sampled[idx[j], idx[i]] += 1\n",{"type":69,"tag":186,"props":2716,"children":2717},{"class":188,"line":1390},[2718],{"type":69,"tag":186,"props":2719,"children":2720},{},[2721],{"type":75,"value":2722},"                    if labels[i] == labels[j]:\n",{"type":69,"tag":186,"props":2724,"children":2725},{"class":188,"line":1399},[2726],{"type":69,"tag":186,"props":2727,"children":2728},{},[2729],{"type":75,"value":2730},"                        co_occurrence[idx[i], idx[j]] += 1\n",{"type":69,"tag":186,"props":2732,"children":2733},{"class":188,"line":1408},[2734],{"type":69,"tag":186,"props":2735,"children":2736},{},[2737],{"type":75,"value":2738},"                        co_occurrence[idx[j], idx[i]] += 1\n",{"type":69,"tag":186,"props":2740,"children":2741},{"class":188,"line":1417},[2742],{"type":69,"tag":186,"props":2743,"children":2744},{"emptyLinePlaceholder":211},[2745],{"type":75,"value":214},{"type":69,"tag":186,"props":2747,"children":2748},{"class":188,"line":1426},[2749],{"type":69,"tag":186,"props":2750,"children":2751},{},[2752],{"type":75,"value":2753},"        # Consensus matrix\n",{"type":69,"tag":186,"props":2755,"children":2756},{"class":188,"line":1435},[2757],{"type":69,"tag":186,"props":2758,"children":2759},{},[2760],{"type":75,"value":2761},"        with np.errstate(divide=\"ignore\", invalid=\"ignore\"):\n",{"type":69,"tag":186,"props":2763,"children":2764},{"class":188,"line":1443},[2765],{"type":69,"tag":186,"props":2766,"children":2767},{},[2768],{"type":75,"value":2769},"            consensus = np.where(co_sampled > 0, co_occurrence \u002F co_sampled, 0)\n",{"type":69,"tag":186,"props":2771,"children":2772},{"class":188,"line":1451},[2773],{"type":69,"tag":186,"props":2774,"children":2775},{"emptyLinePlaceholder":211},[2776],{"type":75,"value":214},{"type":69,"tag":186,"props":2778,"children":2779},{"class":188,"line":1460},[2780],{"type":69,"tag":186,"props":2781,"children":2782},{},[2783],{"type":75,"value":2784},"        # Final clustering on consensus matrix\n",{"type":69,"tag":186,"props":2786,"children":2787},{"class":188,"line":1468},[2788],{"type":69,"tag":186,"props":2789,"children":2790},{},[2791],{"type":75,"value":2792},"        km_final = KMeans(n_clusters=k, n_init=10, random_state=seed)\n",{"type":69,"tag":186,"props":2794,"children":2795},{"class":188,"line":1477},[2796],{"type":69,"tag":186,"props":2797,"children":2798},{},[2799],{"type":75,"value":2800},"        final_labels = km_final.fit_predict(1 - consensus)  # distance = 1 - consensus\n",{"type":69,"tag":186,"props":2802,"children":2803},{"class":188,"line":1486},[2804],{"type":69,"tag":186,"props":2805,"children":2806},{},[2807],{"type":75,"value":2808},"        sil = silhouette_score(1 - consensus, final_labels, metric=\"precomputed\")\n",{"type":69,"tag":186,"props":2810,"children":2811},{"class":188,"line":1494},[2812],{"type":69,"tag":186,"props":2813,"children":2814},{"emptyLinePlaceholder":211},[2815],{"type":75,"value":214},{"type":69,"tag":186,"props":2817,"children":2818},{"class":188,"line":1503},[2819],{"type":69,"tag":186,"props":2820,"children":2821},{},[2822],{"type":75,"value":2823},"        results[k] = {\"consensus_matrix\": consensus, \"silhouette\": sil, \"labels\": final_labels}\n",{"type":69,"tag":186,"props":2825,"children":2826},{"class":188,"line":1512},[2827],{"type":69,"tag":186,"props":2828,"children":2829},{},[2830],{"type":75,"value":2831},"        print(f\"k={k}: silhouette={sil:.3f}\")\n",{"type":69,"tag":186,"props":2833,"children":2835},{"class":188,"line":2834},42,[2836],{"type":69,"tag":186,"props":2837,"children":2838},{"emptyLinePlaceholder":211},[2839],{"type":75,"value":214},{"type":69,"tag":186,"props":2841,"children":2843},{"class":188,"line":2842},43,[2844],{"type":69,"tag":186,"props":2845,"children":2846},{},[2847],{"type":75,"value":2848},"    return results\n",{"type":69,"tag":186,"props":2850,"children":2852},{"class":188,"line":2851},44,[2853],{"type":69,"tag":186,"props":2854,"children":2855},{"emptyLinePlaceholder":211},[2856],{"type":75,"value":214},{"type":69,"tag":186,"props":2858,"children":2860},{"class":188,"line":2859},45,[2861],{"type":69,"tag":186,"props":2862,"children":2863},{},[2864],{"type":75,"value":2865},"# Usage with MOFA factors\n",{"type":69,"tag":186,"props":2867,"children":2869},{"class":188,"line":2868},46,[2870],{"type":69,"tag":186,"props":2871,"children":2872},{},[2873],{"type":75,"value":2874},"# factors: samples x factors array from MOFA\n",{"type":69,"tag":186,"props":2876,"children":2878},{"class":188,"line":2877},47,[2879],{"type":69,"tag":186,"props":2880,"children":2881},{},[2882],{"type":75,"value":2883},"results = consensus_clustering(factors, k_range=range(2, 9))\n",{"type":69,"tag":186,"props":2885,"children":2887},{"class":188,"line":2886},48,[2888],{"type":69,"tag":186,"props":2889,"children":2890},{"emptyLinePlaceholder":211},[2891],{"type":75,"value":214},{"type":69,"tag":186,"props":2893,"children":2895},{"class":188,"line":2894},49,[2896],{"type":69,"tag":186,"props":2897,"children":2898},{},[2899],{"type":75,"value":2900},"# Select optimal k by maximum silhouette score\n",{"type":69,"tag":186,"props":2902,"children":2904},{"class":188,"line":2903},50,[2905],{"type":69,"tag":186,"props":2906,"children":2907},{},[2908],{"type":75,"value":2909},"optimal_k = max(results, key=lambda k: results[k][\"silhouette\"])\n",{"type":69,"tag":186,"props":2911,"children":2913},{"class":188,"line":2912},51,[2914],{"type":69,"tag":186,"props":2915,"children":2916},{},[2917],{"type":75,"value":2918},"print(f\"Optimal k: {optimal_k}\")\n",{"type":69,"tag":167,"props":2920,"children":2922},{"id":2921},"r-consensusclusterplus",[2923],{"type":75,"value":2924},"R — ConsensusClusterPlus",{"type":69,"tag":174,"props":2926,"children":2928},{"className":407,"code":2927,"language":409,"meta":179,"style":179},"library(ConsensusClusterPlus)\n# input_mat: features x samples\nresults \u003C- ConsensusClusterPlus(\n  d = input_mat,\n  maxK = 8,\n  reps = 1000,\n  pItem = 0.8,        # proportion of samples to subsample\n  pFeature = 1,       # use all features\n  clusterAlg = \"km\",  # k-means\n  distance = \"euclidean\",\n  seed = 42,\n  plot = \"pdf\",\n  title = \"consensus_clustering\"\n)\n\n# Inspect consensus CDF and delta area plots in output PDF\n# Select k where CDF curve is flattest (highest consensus)\n",[2929],{"type":69,"tag":182,"props":2930,"children":2931},{"__ignoreMap":179},[2932,2940,2948,2956,2964,2972,2980,2988,2996,3004,3012,3020,3028,3036,3043,3050,3058],{"type":69,"tag":186,"props":2933,"children":2934},{"class":188,"line":189},[2935],{"type":69,"tag":186,"props":2936,"children":2937},{},[2938],{"type":75,"value":2939},"library(ConsensusClusterPlus)\n",{"type":69,"tag":186,"props":2941,"children":2942},{"class":188,"line":198},[2943],{"type":69,"tag":186,"props":2944,"children":2945},{},[2946],{"type":75,"value":2947},"# input_mat: features x samples\n",{"type":69,"tag":186,"props":2949,"children":2950},{"class":188,"line":207},[2951],{"type":69,"tag":186,"props":2952,"children":2953},{},[2954],{"type":75,"value":2955},"results \u003C- ConsensusClusterPlus(\n",{"type":69,"tag":186,"props":2957,"children":2958},{"class":188,"line":26},[2959],{"type":69,"tag":186,"props":2960,"children":2961},{},[2962],{"type":75,"value":2963},"  d = input_mat,\n",{"type":69,"tag":186,"props":2965,"children":2966},{"class":188,"line":225},[2967],{"type":69,"tag":186,"props":2968,"children":2969},{},[2970],{"type":75,"value":2971},"  maxK = 8,\n",{"type":69,"tag":186,"props":2973,"children":2974},{"class":188,"line":233},[2975],{"type":69,"tag":186,"props":2976,"children":2977},{},[2978],{"type":75,"value":2979},"  reps = 1000,\n",{"type":69,"tag":186,"props":2981,"children":2982},{"class":188,"line":242},[2983],{"type":69,"tag":186,"props":2984,"children":2985},{},[2986],{"type":75,"value":2987},"  pItem = 0.8,        # proportion of samples to subsample\n",{"type":69,"tag":186,"props":2989,"children":2990},{"class":188,"line":251},[2991],{"type":69,"tag":186,"props":2992,"children":2993},{},[2994],{"type":75,"value":2995},"  pFeature = 1,       # use all features\n",{"type":69,"tag":186,"props":2997,"children":2998},{"class":188,"line":259},[2999],{"type":69,"tag":186,"props":3000,"children":3001},{},[3002],{"type":75,"value":3003},"  clusterAlg = \"km\",  # k-means\n",{"type":69,"tag":186,"props":3005,"children":3006},{"class":188,"line":268},[3007],{"type":69,"tag":186,"props":3008,"children":3009},{},[3010],{"type":75,"value":3011},"  distance = \"euclidean\",\n",{"type":69,"tag":186,"props":3013,"children":3014},{"class":188,"line":277},[3015],{"type":69,"tag":186,"props":3016,"children":3017},{},[3018],{"type":75,"value":3019},"  seed = 42,\n",{"type":69,"tag":186,"props":3021,"children":3022},{"class":188,"line":286},[3023],{"type":69,"tag":186,"props":3024,"children":3025},{},[3026],{"type":75,"value":3027},"  plot = \"pdf\",\n",{"type":69,"tag":186,"props":3029,"children":3030},{"class":188,"line":295},[3031],{"type":69,"tag":186,"props":3032,"children":3033},{},[3034],{"type":75,"value":3035},"  title = \"consensus_clustering\"\n",{"type":69,"tag":186,"props":3037,"children":3038},{"class":188,"line":304},[3039],{"type":69,"tag":186,"props":3040,"children":3041},{},[3042],{"type":75,"value":328},{"type":69,"tag":186,"props":3044,"children":3045},{"class":188,"line":313},[3046],{"type":69,"tag":186,"props":3047,"children":3048},{"emptyLinePlaceholder":211},[3049],{"type":75,"value":214},{"type":69,"tag":186,"props":3051,"children":3052},{"class":188,"line":322},[3053],{"type":69,"tag":186,"props":3054,"children":3055},{},[3056],{"type":75,"value":3057},"# Inspect consensus CDF and delta area plots in output PDF\n",{"type":69,"tag":186,"props":3059,"children":3060},{"class":188,"line":331},[3061],{"type":69,"tag":186,"props":3062,"children":3063},{},[3064],{"type":75,"value":3065},"# Select k where CDF curve is flattest (highest consensus)\n",{"type":69,"tag":167,"props":3067,"children":3069},{"id":3068},"consensus-clustering-parameter-table",[3070],{"type":75,"value":3071},"Consensus Clustering Parameter Table",{"type":69,"tag":537,"props":3073,"children":3074},{},[3075,3095],{"type":69,"tag":541,"props":3076,"children":3077},{},[3078],{"type":69,"tag":545,"props":3079,"children":3080},{},[3081,3085,3090],{"type":69,"tag":549,"props":3082,"children":3083},{},[3084],{"type":75,"value":553},{"type":69,"tag":549,"props":3086,"children":3087},{},[3088],{"type":75,"value":3089},"Python (custom)",{"type":69,"tag":549,"props":3091,"children":3092},{},[3093],{"type":75,"value":3094},"R (ConsensusClusterPlus)",{"type":69,"tag":565,"props":3096,"children":3097},{},[3098,3124,3150,3172,3194],{"type":69,"tag":545,"props":3099,"children":3100},{},[3101,3106,3115],{"type":69,"tag":572,"props":3102,"children":3103},{},[3104],{"type":75,"value":3105},"k range",{"type":69,"tag":572,"props":3107,"children":3108},{},[3109],{"type":69,"tag":182,"props":3110,"children":3112},{"className":3111},[],[3113],{"type":75,"value":3114},"k_range=range(2, 9)",{"type":69,"tag":572,"props":3116,"children":3117},{},[3118],{"type":69,"tag":182,"props":3119,"children":3121},{"className":3120},[],[3122],{"type":75,"value":3123},"maxK = 8",{"type":69,"tag":545,"props":3125,"children":3126},{},[3127,3132,3141],{"type":69,"tag":572,"props":3128,"children":3129},{},[3130],{"type":75,"value":3131},"Iterations",{"type":69,"tag":572,"props":3133,"children":3134},{},[3135],{"type":69,"tag":182,"props":3136,"children":3138},{"className":3137},[],[3139],{"type":75,"value":3140},"n_iterations=100",{"type":69,"tag":572,"props":3142,"children":3143},{},[3144],{"type":69,"tag":182,"props":3145,"children":3147},{"className":3146},[],[3148],{"type":75,"value":3149},"reps = 1000",{"type":69,"tag":545,"props":3151,"children":3152},{},[3153,3158,3163],{"type":69,"tag":572,"props":3154,"children":3155},{},[3156],{"type":75,"value":3157},"Subsample fraction",{"type":69,"tag":572,"props":3159,"children":3160},{},[3161],{"type":75,"value":3162},"0.8 (hardcoded)",{"type":69,"tag":572,"props":3164,"children":3165},{},[3166],{"type":69,"tag":182,"props":3167,"children":3169},{"className":3168},[],[3170],{"type":75,"value":3171},"pItem = 0.8",{"type":69,"tag":545,"props":3173,"children":3174},{},[3175,3180,3185],{"type":69,"tag":572,"props":3176,"children":3177},{},[3178],{"type":75,"value":3179},"Algorithm",{"type":69,"tag":572,"props":3181,"children":3182},{},[3183],{"type":75,"value":3184},"KMeans",{"type":69,"tag":572,"props":3186,"children":3187},{},[3188],{"type":69,"tag":182,"props":3189,"children":3191},{"className":3190},[],[3192],{"type":75,"value":3193},"clusterAlg = \"km\"",{"type":69,"tag":545,"props":3195,"children":3196},{},[3197,3202,3207],{"type":69,"tag":572,"props":3198,"children":3199},{},[3200],{"type":75,"value":3201},"Selection criterion",{"type":69,"tag":572,"props":3203,"children":3204},{},[3205],{"type":75,"value":3206},"Silhouette score",{"type":69,"tag":572,"props":3208,"children":3209},{},[3210],{"type":75,"value":3211},"CDF delta area plot",{"type":69,"tag":123,"props":3213,"children":3214},{},[],{"type":69,"tag":78,"props":3216,"children":3218},{"id":3217},"common-mistakes",[3219],{"type":75,"value":3220},"Common Mistakes",{"type":69,"tag":97,"props":3222,"children":3223},{},[3224,3249,3278,3307,3336],{"type":69,"tag":101,"props":3225,"children":3226},{},[3227,3233,3235,3240,3242,3247],{"type":69,"tag":3228,"props":3229,"children":3230},"strong",{},[3231],{"type":75,"value":3232},"Wrong:",{"type":75,"value":3234}," Mapping gene IDs using symbol-based joins without handling duplicates or deprecated symbols\n",{"type":69,"tag":3228,"props":3236,"children":3237},{},[3238],{"type":75,"value":3239},"Right:",{"type":75,"value":3241}," Use HGNC ID or Ensembl stable ID as the primary key; resolve ambiguous symbols via the HGNC multi-symbol checker\n",{"type":69,"tag":3228,"props":3243,"children":3244},{},[3245],{"type":75,"value":3246},"Why:",{"type":75,"value":3248}," Gene symbols are not unique (e.g., \"MARCH1\" was renamed to \"MARCHF1\") — symbol joins silently drop or duplicate rows",{"type":69,"tag":101,"props":3250,"children":3251},{},[3252,3256,3258,3262,3264,3270,3272,3276],{"type":69,"tag":3228,"props":3253,"children":3254},{},[3255],{"type":75,"value":3232},{"type":75,"value":3257}," Running ComBat without including biological covariates in the model matrix\n",{"type":69,"tag":3228,"props":3259,"children":3260},{},[3261],{"type":75,"value":3239},{"type":75,"value":3263}," Always pass ",{"type":69,"tag":182,"props":3265,"children":3267},{"className":3266},[],[3268],{"type":75,"value":3269},"mod = model.matrix(~ disease_status + sex, data=meta)",{"type":75,"value":3271}," to protect biological signal\n",{"type":69,"tag":3228,"props":3273,"children":3274},{},[3275],{"type":75,"value":3246},{"type":75,"value":3277}," Without protected covariates, ComBat removes biological variation that correlates with batch",{"type":69,"tag":101,"props":3279,"children":3280},{},[3281,3285,3287,3293,3295,3299,3301,3305],{"type":69,"tag":3228,"props":3282,"children":3283},{},[3284],{"type":75,"value":3232},{"type":75,"value":3286}," Using ",{"type":69,"tag":182,"props":3288,"children":3290},{"className":3289},[],[3291],{"type":75,"value":3292},"mofapy2",{"type":75,"value":3294}," with raw counts instead of normalized, variance-stabilized data\n",{"type":69,"tag":3228,"props":3296,"children":3297},{},[3298],{"type":75,"value":3239},{"type":75,"value":3300}," Apply log2(CPM+1) or VST to RNA-seq counts before passing to MOFA; use log2 intensity for proteomics\n",{"type":69,"tag":3228,"props":3302,"children":3303},{},[3304],{"type":75,"value":3246},{"type":75,"value":3306}," MOFA assumes Gaussian-distributed continuous data — raw counts violate this and produce meaningless factors",{"type":69,"tag":101,"props":3308,"children":3309},{},[3310,3314,3316,3320,3322,3328,3330,3334],{"type":69,"tag":3228,"props":3311,"children":3312},{},[3313],{"type":75,"value":3232},{"type":75,"value":3315}," Running gseapy\u002Ffgsea with a gene list ranked by fold change alone (no significance weighting)\n",{"type":69,"tag":3228,"props":3317,"children":3318},{},[3319],{"type":75,"value":3239},{"type":75,"value":3321}," Rank by ",{"type":69,"tag":182,"props":3323,"children":3325},{"className":3324},[],[3326],{"type":75,"value":3327},"-log10(p) × sign(log2FC)",{"type":75,"value":3329}," or use the Wald statistic from DESeq2\u002Flimma\n",{"type":69,"tag":3228,"props":3331,"children":3332},{},[3333],{"type":75,"value":3246},{"type":75,"value":3335}," Fold-change-only ranking treats noisy large-FC genes the same as significant ones, inflating false enrichments",{"type":69,"tag":101,"props":3337,"children":3338},{},[3339,3343,3345,3351,3353,3357,3359,3365,3367,3371],{"type":69,"tag":3228,"props":3340,"children":3341},{},[3342],{"type":75,"value":3232},{"type":75,"value":3344}," Using default ",{"type":69,"tag":182,"props":3346,"children":3348},{"className":3347},[],[3349],{"type":75,"value":3350},"min_size=1",{"type":75,"value":3352}," in fgsea, allowing tiny gene sets to appear significant\n",{"type":69,"tag":3228,"props":3354,"children":3355},{},[3356],{"type":75,"value":3239},{"type":75,"value":3358}," Set ",{"type":69,"tag":182,"props":3360,"children":3362},{"className":3361},[],[3363],{"type":75,"value":3364},"minSize=15, maxSize=500",{"type":75,"value":3366}," to filter gene sets to biologically interpretable sizes\n",{"type":69,"tag":3228,"props":3368,"children":3369},{},[3370],{"type":75,"value":3246},{"type":75,"value":3372}," Very small gene sets produce unstable enrichment scores; very large sets are too generic to be informative",{"type":69,"tag":3374,"props":3375,"children":3376},"style",{},[3377],{"type":75,"value":3378},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":3380,"total":1503},[3381,3401,3414,3428,3443,3456,3469],{"slug":3382,"name":3382,"fn":3383,"description":3384,"org":3385,"tags":3386,"stars":26,"repoUrl":27,"updatedAt":3400},"aws-genai-ml-architect","design AWS GenAI and ML architectures","Reasoning skill for designing AWS GenAI and ML architectures for healthcare and life sciences workloads. Use when the user asks to choose between SageMaker and Bedrock, design a RAG system over medical literature, architect clinical NLP or medical imaging inference, plan genomics or drug discovery pipelines on AWS, address HIPAA\u002FPHI compliance in ML systems, design MLOps for regulated clinical models, or optimize cost for HCLS ML workloads. Triggers include \"AWS architecture\", \"SageMaker vs Bedrock\", \"HIPAA ML\", \"clinical RAG\", \"medical imaging inference\", \"genomics on AWS\", \"PHI training\", \"MLOps healthcare\", \"Bedrock guardrails\", \"HealthLake\", \"HCLS cloud architecture\", \"BAA compliance\", \"SageMaker endpoint\", \"Bedrock knowledge base\", \"clinical NLP on AWS\", \"FDA SaMD on AWS\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3387,3390,3393,3396,3397],{"name":3388,"slug":3389,"type":16},"Architecture","architecture",{"name":3391,"slug":3392,"type":16},"AWS","aws",{"name":3394,"slug":3395,"type":16},"Healthcare","healthcare",{"name":21,"slug":22,"type":16},{"name":3398,"slug":3399,"type":16},"LLM","llm","2026-07-12T08:38:07.975937",{"slug":3402,"name":3402,"fn":3403,"description":3404,"org":3405,"tags":3406,"stars":26,"repoUrl":27,"updatedAt":3413},"biomarker-discovery","guide biomarker discovery and validation","Reason about biomarker discovery and validation in HCLS — classifying biomarker intent, choosing feature-selection and cross-validation strategies, avoiding leakage, and planning external replication. Use when the user asks to discover, develop, or validate a biomarker; select features from high-dimensional omics or clinical data; design a validation study; choose evaluation metrics; justify sample size; combine multi-omics signals; or assess clinical utility. Triggers include \"discover a biomarker\", \"validate biomarker\", \"prognostic vs predictive\", \"feature selection\", \"LASSO vs elastic net\", \"nested cross-validation\", \"data leakage\", \"C-index\", \"time-dependent AUC\", \"decision curve analysis\", \"external validation cohort\", \"events per variable\", \"optimism-corrected\", \"multi-omics integration\", \"clinical utility of a biomarker\", \"is this biomarker ready\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3407,3408,3409,3410],{"name":3391,"slug":3392,"type":16},{"name":24,"slug":25,"type":16},{"name":21,"slug":22,"type":16},{"name":3411,"slug":3412,"type":16},"Research","research","2026-07-12T08:37:49.295301",{"slug":3415,"name":3415,"fn":3416,"description":3417,"org":3418,"tags":3419,"stars":26,"repoUrl":27,"updatedAt":3427},"cdisc-compliance","reason about CDISC SDTM and ADaM implementation","Reason about CDISC SDTM and ADaM implementation for regulatory submissions. Use when the user asks about SDTM domain mapping, ADaM dataset design, controlled terminology versioning, define.xml completeness, FDA or PMDA submission requirements, query prioritization by clinical impact, SUPPQUAL usage, or CDISC compliance review. Triggers include \"SDTM mapping\", \"ADaM dataset\", \"CDISC compliance\", \"controlled terminology\", \"define.xml\", \"FDA submission data\", \"PMDA submission\", \"SDTM domain\", \"ADSL\", \"ADAE\", \"ADLB\", \"BDS structure\", \"SUPPQUAL\", \"RELREC\", \"value-level metadata\", \"CDISC CT\", \"regulatory submission data standards\", \"eCTD datasets\", \"SDTM 3.3\", \"ADaM 1.1\", \"query prioritization\", \"clinical data review\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3420,3423,3424],{"name":3421,"slug":3422,"type":16},"Clinical Trials","clinical-trials",{"name":21,"slug":22,"type":16},{"name":3425,"slug":3426,"type":16},"Regulatory Compliance","regulatory-compliance","2026-07-12T08:37:33.35594",{"slug":3429,"name":3429,"fn":3430,"description":3431,"org":3432,"tags":3433,"stars":26,"repoUrl":27,"updatedAt":3442},"cell-type-annotation","annotate single-cell RNA-seq clusters","Generate code to assign cell type labels to single-cell RNA-seq clusters using CellTypist, SingleR, marker-based annotation, or reference label transfer (scANVI\u002Fingest). Triggers on requests to \"annotate cell types\", \"label clusters\", \"run CellTypist\", \"SingleR annotation\", \"marker gene dotplot\", \"transfer labels from reference atlas\", \"cell identity\", \"automated annotation\", \"reference mapping\", \"scANVI label transfer\", \"canonical markers\", \"immune cell types\", \"hierarchical annotation\", \"majority voting CellTypist\", \"over-clustering annotation\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3434,3435,3438,3439],{"name":24,"slug":25,"type":16},{"name":3436,"slug":3437,"type":16},"Data Analysis","data-analysis",{"name":21,"slug":22,"type":16},{"name":3440,"slug":3441,"type":16},"RNA-seq","rna-seq","2026-07-12T08:38:05.443454",{"slug":3444,"name":3444,"fn":3445,"description":3446,"org":3447,"tags":3448,"stars":26,"repoUrl":27,"updatedAt":3455},"cheminformatics","calculate molecular properties with RDKit","Cheminformatics pipeline for small-molecule property calculation, filtering, and similarity analysis using RDKit. Use when the user asks to compute molecular descriptors, filter compounds by Lipinski or Veber rules, detect PAINS, calculate fingerprint similarity, run matched molecular pair analysis, generate ADMET descriptors, or process SMILES. Triggers include \"RDKit\", \"molecular descriptors\", \"Lipinski\", \"rule of five\", \"Veber\", \"PAINS\", \"pan-assay interference\", \"Morgan fingerprint\", \"Tanimoto\", \"fingerprint similarity\", \"matched molecular pair\", \"MMP\", \"mmpdb\", \"ADMET\", \"druglikeness\", \"SMILES\", \"cheminformatics\", \"compound filtering\", \"chemical similarity\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3449,3450,3453,3454],{"name":24,"slug":25,"type":16},{"name":3451,"slug":3452,"type":16},"Chemistry","chemistry",{"name":3436,"slug":3437,"type":16},{"name":3411,"slug":3412,"type":16},"2026-07-12T08:37:28.334619",{"slug":3457,"name":3457,"fn":3458,"description":3459,"org":3460,"tags":3461,"stars":26,"repoUrl":27,"updatedAt":3468},"claims-analytics","analyze and parse healthcare claims data","Pipeline skill for healthcare claims data parsing, analysis, and fraud detection. Use when the user asks to parse X12 837 or 835 claim files, manipulate ICD-10 CPT or HCPCS codes, detect billing pattern anomalies, profile providers against specialty peers, identify outlier billing behavior, validate NCCI edits programmatically, detect duplicate claims, run Benford's law analysis on charges, build claims data pipelines, or analyze E&M code distributions. Triggers include \"parse X12 837\", \"parse 835\", \"claims SQL\", \"ICD-10 manipulation\", \"CPT code analysis\", \"provider profiling\", \"billing outlier\", \"NCCI validation code\", \"duplicate claim detection\", \"Benford's law charges\", \"claims ETL\", \"E&M distribution analysis\", \"claims analytics pipeline\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3462,3463,3464,3467],{"name":3436,"slug":3437,"type":16},{"name":3394,"slug":3395,"type":16},{"name":3465,"slug":3466,"type":16},"Insurance","insurance",{"name":21,"slug":22,"type":16},"2026-07-12T08:37:34.815088",{"slug":3470,"name":3470,"fn":3471,"description":3472,"org":3473,"tags":3474,"stars":26,"repoUrl":27,"updatedAt":3478},"claims-billing-rules","analyze healthcare claims billing rules","Reasoning skill for healthcare claims billing rules and fraud detection logic. Use when the user asks about CMS billing rules, place of service codes, global surgery periods, modifier usage (25 59 76 77), NCCI edit logic, column 1 column 2 code pairs, mutually exclusive procedures, modifier indicators, fraud waste and abuse patterns, E&M upcoding, unbundling, phantom billing, impossible day detection, coding error versus fraud distinction, FWA investigation methodology, or claims audit logic. Triggers include \"CMS billing rules\", \"NCCI edits\", \"modifier 25\", \"modifier 59\", \"global surgery period\", \"upcoding\", \"unbundling\", \"phantom billing\", \"impossible day\", \"FWA\", \"fraud waste abuse\", \"coding error vs fraud\", \"claims audit\", \"billing compliance\", \"E&M level selection\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3475,3476,3477],{"name":3394,"slug":3395,"type":16},{"name":3465,"slug":3466,"type":16},{"name":3425,"slug":3426,"type":16},"2026-07-12T08:38:28.210856",{"items":3480,"total":3656},[3481,3500,3521,3531,3544,3557,3567,3577,3598,3613,3628,3643],{"slug":3482,"name":3482,"fn":3483,"description":3484,"org":3485,"tags":3486,"stars":3497,"repoUrl":3498,"updatedAt":3499},"agentcore-investigation","investigate Bedrock AgentCore runtime sessions","Investigate Bedrock AgentCore runtime sessions via CloudWatch Logs Insights — resolve session\u002Ftrace IDs, query OTEL spans, filter noise, build timelines. Use when debugging AgentCore agent sessions, tracing tool calls, or analyzing latency.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3487,3488,3491,3494],{"name":3391,"slug":3392,"type":16},{"name":3489,"slug":3490,"type":16},"Debugging","debugging",{"name":3492,"slug":3493,"type":16},"Logs","logs",{"name":3495,"slug":3496,"type":16},"Observability","observability",9427,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fmcp","2026-07-12T08:37:22.601527",{"slug":3501,"name":3502,"fn":3503,"description":3504,"org":3505,"tags":3506,"stars":3497,"repoUrl":3498,"updatedAt":3520},"amazon-aurora-dsql","amazon aurora dsql","build applications with Aurora DSQL","Build with Aurora DSQL — manage schemas, execute queries, handle migrations, diagnose query plans, load data, and develop applications with a serverless, distributed SQL database. Covers IAM auth, multi-tenant patterns, MySQL-to-DSQL and PostgreSQL-to-DSQL schema conversion, FK replacement code generation, OCC retry patterns, ORM migration (Django\u002FHibernate\u002FRails), DDL operations, query plan explainability, SQL compatibility validation, and bulk data loading. Triggers on phrases like: DSQL, Aurora DSQL, create DSQL table, DSQL schema, migrate to DSQL, distributed SQL database, serverless PostgreSQL-compatible database, DSQL query plan, DSQL EXPLAIN ANALYZE, why is my DSQL query slow, DSQL foreign key, DSQL OCC retry, DSQL multi-region, load into DSQL, load CSV into DSQL, bulk load DSQL, aurora-dsql-loader.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3507,3510,3511,3514,3517],{"name":3508,"slug":3509,"type":16},"Aurora","aurora",{"name":3391,"slug":3392,"type":16},{"name":3512,"slug":3513,"type":16},"Database","database",{"name":3515,"slug":3516,"type":16},"Serverless","serverless",{"name":3518,"slug":3519,"type":16},"SQL","sql","2026-07-12T08:36:45.053393",{"slug":3522,"name":3523,"fn":3503,"description":3504,"org":3524,"tags":3525,"stars":3497,"repoUrl":3498,"updatedAt":3530},"aurora-dsql","aurora dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3526,3527,3528,3529],{"name":3391,"slug":3392,"type":16},{"name":3512,"slug":3513,"type":16},{"name":3515,"slug":3516,"type":16},{"name":3518,"slug":3519,"type":16},"2026-07-12T08:36:42.694299",{"slug":3532,"name":3533,"fn":3503,"description":3504,"org":3534,"tags":3535,"stars":3497,"repoUrl":3498,"updatedAt":3543},"aws-dsql","aws dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3536,3537,3538,3541,3542],{"name":3391,"slug":3392,"type":16},{"name":3512,"slug":3513,"type":16},{"name":3539,"slug":3540,"type":16},"Migration","migration",{"name":3515,"slug":3516,"type":16},{"name":3518,"slug":3519,"type":16},"2026-07-12T08:36:38.584057",{"slug":3545,"name":3546,"fn":3503,"description":3504,"org":3547,"tags":3548,"stars":3497,"repoUrl":3498,"updatedAt":3556},"distributed-postgres","distributed postgres",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3549,3550,3551,3554,3555],{"name":3391,"slug":3392,"type":16},{"name":3512,"slug":3513,"type":16},{"name":3552,"slug":3553,"type":16},"PostgreSQL","postgresql",{"name":3515,"slug":3516,"type":16},{"name":3518,"slug":3519,"type":16},"2026-07-12T08:36:46.530743",{"slug":3558,"name":3559,"fn":3503,"description":3504,"org":3560,"tags":3561,"stars":3497,"repoUrl":3498,"updatedAt":3566},"distributed-sql","distributed sql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3562,3563,3564,3565],{"name":3391,"slug":3392,"type":16},{"name":3512,"slug":3513,"type":16},{"name":3515,"slug":3516,"type":16},{"name":3518,"slug":3519,"type":16},"2026-07-12T08:36:48.104182",{"slug":3568,"name":3568,"fn":3503,"description":3504,"org":3569,"tags":3570,"stars":3497,"repoUrl":3498,"updatedAt":3576},"dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3571,3572,3573,3574,3575],{"name":3391,"slug":3392,"type":16},{"name":3512,"slug":3513,"type":16},{"name":3539,"slug":3540,"type":16},{"name":3515,"slug":3516,"type":16},{"name":3518,"slug":3519,"type":16},"2026-07-12T08:36:36.374512",{"slug":3578,"name":3578,"fn":3579,"description":3580,"org":3581,"tags":3582,"stars":3595,"repoUrl":3596,"updatedAt":3597},"cost-efficiency-analyzer","analyze cost efficiency and expenses","Analyzes cost structure, cost efficiency, and expense management from P&L data. Use when the user asks about costs, expenses, COGS, operating expenses, cost ratios, cost control, spending efficiency, margin compression from cost side, or wants to understand where money is going. Also use for \"are we spending too much\", \"cost breakdown\", \"expense analysis\", or \"how efficient are our operations\". NOT for revenue or top-line analysis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3583,3586,3589,3592],{"name":3584,"slug":3585,"type":16},"Accounting","accounting",{"name":3587,"slug":3588,"type":16},"Analytics","analytics",{"name":3590,"slug":3591,"type":16},"Cost Optimization","cost-optimization",{"name":3593,"slug":3594,"type":16},"Finance","finance",3176,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fagentcore-samples","2026-07-12T08:40:03.29555",{"slug":3599,"name":3599,"fn":3600,"description":3601,"org":3602,"tags":3603,"stars":3595,"repoUrl":3596,"updatedAt":3612},"executive-financial-briefing","generate executive financial briefings","Generates a concise executive-level financial briefing or summary suitable for a CEO, CFO, or board presentation. Use when the user asks for a summary, briefing, executive summary, board update, financial overview, financial health check, or \"how is the business doing\". Covers the full P&L picture in one page. Also use for \"give me the highlights\", \"what do I need to know\", or \"quick financial update\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3604,3605,3606,3609],{"name":3391,"slug":3392,"type":16},{"name":3593,"slug":3594,"type":16},{"name":3607,"slug":3608,"type":16},"Management","management",{"name":3610,"slug":3611,"type":16},"Reporting","reporting","2026-07-12T08:40:02.066471",{"slug":3614,"name":3614,"fn":3615,"description":3616,"org":3617,"tags":3618,"stars":3595,"repoUrl":3596,"updatedAt":3627},"multi-quarter-trend-analysis","analyze multi-quarter financial trends","Analyzes financial trends across multiple quarters by comparing P&L metrics over time. Use when the user wants to see trends, patterns, trajectories, or directional movement across 3 or more quarters. Also use for \"how are we trending\", \"show me the trend\", \"track performance over time\", \"quarter over quarter comparison across all quarters\", or any multi-period longitudinal analysis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3619,3620,3621,3624],{"name":3587,"slug":3588,"type":16},{"name":3593,"slug":3594,"type":16},{"name":3622,"slug":3623,"type":16},"Financial Statements","financial-statements",{"name":3625,"slug":3626,"type":16},"Variance Analysis","variance-analysis","2026-07-12T08:40:00.79141",{"slug":3629,"name":3629,"fn":3630,"description":3631,"org":3632,"tags":3633,"stars":3595,"repoUrl":3596,"updatedAt":3642},"pdf","process and manipulate PDF documents","Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text\u002Ftables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting\u002Fdecrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3634,3637,3640],{"name":3635,"slug":3636,"type":16},"Automation","automation",{"name":3638,"slug":3639,"type":16},"Documents","documents",{"name":3641,"slug":3629,"type":16},"PDF","2026-07-12T08:41:44.135656",{"slug":3644,"name":3644,"fn":3645,"description":3646,"org":3647,"tags":3648,"stars":3595,"repoUrl":3596,"updatedAt":3655},"quarterly-kpi-calculator","calculate quarterly financial KPIs","Calculates quarterly financial KPIs from P&L data. P&L figures can be provided directly by the user or fetched from the financial data MCP server. Use when the user wants KPI calculations such as Gross Margin %, EBITDA Margin %, Operating Expense Ratio, or Revenue Growth % QoQ. Also use for quarterly performance review, P&L analysis, or interpreting financial ratios against benchmarks.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3649,3650,3651,3652],{"name":3584,"slug":3585,"type":16},{"name":3436,"slug":3437,"type":16},{"name":3593,"slug":3594,"type":16},{"name":3653,"slug":3654,"type":16},"KPI","kpi","2026-07-12T08:39:59.54971",150]