| name | omics-integration |
| description | Multi-omics data integration using MOFA+, DIABLO, and MixOmics for combining genomics, transcriptomics, proteomics, metabolomics, and epigenomics datasets. Use for identifying shared variation across omics layers, building integrative biomarker models, and discovering cross-modal biological patterns. Best for paired multi-omics cohort studies. |
| allowed-tools | Read Write Edit Bash |
| license | MIT license |
| metadata | {"skill-author":"Lord1Egypt"} |
Multi-Omics Integration
Overview
Multi-omics integration combines data from multiple molecular measurement platforms (RNA-seq, proteomics, ATAC-seq, metabolomics, methylation) to identify shared biological variation and cross-modal regulatory relationships. This skill covers MOFA+ for unsupervised factor analysis, MixOmics/DIABLO for supervised integration, and network-based approaches.
When to Use This Skill
- Integrating paired multi-omics datasets (same samples across platforms)
- Identifying latent factors that explain variation across omics layers
- Building multi-omics classifiers or biomarker panels
- Finding correlated features across genomics, transcriptomics, and proteomics
- Studying regulatory cascades (DNA → RNA → protein → metabolite)
- Visualizing multi-omics data in low-dimensional space
- Performing network-based multi-omics enrichment
Quick Start
MOFA+ (Multi-Omics Factor Analysis)
from mofapy2.run.entry_point import entry_point
import pandas as pd
import numpy as np
rna_data = pd.read_csv("rna_normalized.csv", index_col=0)
protein_data = pd.read_csv("protein_lfq.csv", index_col=0)
metabolite_data = pd.read_csv("metabolites.csv", index_col=0)
common_samples = rna_data.index.intersection(protein_data.index).intersection(metabolite_data.index)
rna_data = rna_data.loc[common_samples]
protein_data = protein_data.loc[common_samples]
metabolite_data = metabolite_data.loc[common_samples]
print(f"Shared samples: {len(common_samples)}")
print(f"RNA: {rna_data.shape[1]} features")
print(f"Protein: {protein_data.shape[1]} features")
print(f"Metabolite: {metabolite_data.shape[1]} features")
ent = entry_point()
ent.set_data_options(scale_groups=False, scale_views=False)
ent.set_data_df(
pd.concat([rna_data.T, protein_data.T, metabolite_data.T]),
likelihoods=["gaussian", "gaussian", "gaussian"],
)
ent.set_model_options(factors=15, spikeslab_weights=, ard_factors=, ard_weights=)
ent.set_train_options(=, convergence_mode=, seed=, gpu_mode=)
ent.build()
ent.run()
ent.save()
()
Loading and Interpreting MOFA+ Results
import mofapy2
from mofapy2.core.entry_point import entry_point
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
model = entry_point()
model.load_hdf5("mofa_model.hdf5")
r2 = model.calculate_variance_explained()
for view_name, r2_vals in zip(model.data_opts["views"], r2["r2_per_factor"]):
print(f"\n{view_name} — variance explained per factor:")
for i, r2_val in enumerate(r2_vals):
print(f" Factor {i+1}: {r2_val*100:.1f}%")
Z = model.nodes["Z"].getExpectation()
factors_df = pd.DataFrame(Z, index=common_samples, columns=[f"Factor{i+1}" for i in range(Z.shape[1])])
sample_meta = pd.read_csv("sample_metadata.csv", index_col=0)
fig, ax = plt.subplots(figsize=(8, 6))
scatter = ax.scatter(
factors_df[],
factors_df[],
c=pd.Categorical(sample_meta.loc[common_samples, ]).codes,
cmap=,
s=,
alpha=,
)
ax.set_xlabel(, fontsize=)
ax.set_ylabel(, fontsize=)
ax.set_title(, fontsize=)
plt.tight_layout()
plt.savefig(, dpi=)
DIABLO (Supervised Multi-Omics Integration)
import subprocess
import pandas as pd
import numpy as np
rna_data.to_csv("rna_for_diablo.csv")
protein_data.to_csv("protein_for_diablo.csv")
metabolite_data.to_csv("metabolite_for_diablo.csv")
sample_meta[["condition"]].to_csv("labels_for_diablo.csv")
r_script = """
library(mixOmics)
# Load data
X_rna <- as.matrix(read.csv("rna_for_diablo.csv", row.names=1))
X_protein <- as.matrix(read.csv("protein_for_diablo.csv", row.names=1))
X_metabolite <- as.matrix(read.csv("metabolite_for_diablo.csv", row.names=1))
Y <- read.csv("labels_for_diablo.csv", row.names=1)[,1]
X <- list(RNA = X_rna, Protein = X_protein, Metabolite = X_metabolite)
# Design matrix (strength of connection between data blocks)
design <- matrix(0.1, nrow=3, ncol=3, dimnames=list(names(X), names(X)))
diag(design) <- 0
# Run DIABLO
diablo_res <- block.splsda(X, Y, ncomp=2, design=design)
# Save results
write.csv(diablo_res$variates$RNA, "diablo_rna_components.csv")
write.csv(diablo_res$variates$Protein, "diablo_protein_components.csv")
saveRDS(diablo_res, "diablo_model.rds")
cat("DIABLO complete\\n")
"""
with open("run_diablo.R", "w") as f:
f.write(r_script)
result = subprocess.run(["Rscript", "run_diablo.R"], capture_output=True, text=True)
print(result.stdout)
Correlation Network (WGCNA-style)
import pandas as pd
import numpy as np
import networkx as nx
from scipy.stats import pearsonr, spearmanr
from statsmodels.stats.multitest import multipletests
def build_cross_omics_network(
df1: pd.DataFrame,
df2: pd.DataFrame,
correlation_threshold: float = 0.6,
fdr_threshold: float = 0.05,
corr_method: str = "spearman",
) -> nx.Graph:
"""Build cross-omics correlation network between two feature matrices."""
assert df1.index.equals(df2.index), "Samples must be aligned"
edges = []
for feat1 in df1.columns[:500]:
for feat2 in df2.columns[:500]:
if corr_method == "spearman":
r, p = spearmanr(df1[feat1], df2[feat2])
else:
r, p = pearsonr(df1[feat1], df2[feat2])
if abs(r) > correlation_threshold:
edges.append({"feat1": feat1, "feat2": feat2, "r": r, "p": p})
edges_df = pd.DataFrame(edges)
if len(edges_df) == 0:
print("No edges found above threshold.")
return nx.Graph()
_, fdr, _, _ = multipletests(edges_df[], method=)
edges_df[] = fdr
sig_edges = edges_df[edges_df[] < fdr_threshold]
G = nx.Graph()
_, row sig_edges.iterrows():
G.add_edge(row[], row[], weight=(row[]), r=row[])
()
G
rna_protein_net = build_cross_omics_network(
rna_data.iloc[:, :],
protein_data.iloc[:, :],
correlation_threshold=,
)
SNF — Similarity Network Fusion
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import pairwise_distances
from scipy.stats import rankdata
def build_similarity_matrix(data: np.ndarray, K: int = 20, sigma: float = 0.5) -> np.ndarray:
"""Build patient similarity matrix from omics data."""
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)
dist = pairwise_distances(data_scaled, metric="euclidean")
return np.exp(-dist**2 / (sigma * np.median(dist[dist > 0])))
def snf_fuse(*matrices, K: int = 20, t: int = 20) -> np.ndarray:
"""Simple Similarity Network Fusion."""
n = matrices[0].shape[0]
W_list = list(matrices)
for i in range(len(W_list)):
row_sums = W_list[i].sum(axis=1, keepdims=True)
W_list[i] = W_list[i] / (row_sums + 1e-10)
for _ in range(t):
W_new = []
i ((W_list)):
others = [W_list[j] j ((W_list)) j != i]
avg_others = np.mean(others, axis=)
W_new.append(W_list[i] @ avg_others @ W_list[i].T)
W_list = W_new
np.mean(W_list, axis=)
W_rna = build_similarity_matrix(rna_data.values)
W_protein = build_similarity_matrix(protein_data.values)
W_metabolite = build_similarity_matrix(metabolite_data.values)
fused_matrix = snf_fuse(W_rna, W_protein, W_metabolite, K=, t=)
()
sklearn.cluster SpectralClustering
clustering = SpectralClustering(n_clusters=, affinity=, random_state=)
patient_clusters = clustering.fit_predict(fused_matrix)
()
Integration Strategy Guide
| Approach | Method | Use Case |
|---|
| Unsupervised | MOFA+, SNF | Discovery, patient stratification |
| Supervised | DIABLO, LASSO | Biomarker selection, classification |
| Network | Correlation, WGCNA | Regulatory networks, hub genes |
| Dimensionality | UMAP on concatenated | Visualization, clustering |
| Causal | Mendelian randomization | Causal inference |
Dependencies
pip install mofapy2 pandas numpy scipy networkx matplotlib seaborn
pip install scikit-learn statsmodels