本工具提供了一套完整的解决方案,用于将AnnData对象(h5ad文件)转换为Seurat对象并保存为RDS格式。支持大规模单细胞RNA-seq数据的转换,完整保留元数据、细胞类型注释和降维结果。
- ✅ 完整数据保留: 保留所有元数据、细胞类型、样本信息
- ✅ 降维结果保持: 完整保留UMAP、PCA、t-SNE坐标
- ✅ 大数据支持: 成功处理90k+细胞的数据集
- ✅ 多种输出格式: 支持h5ad、CSV、RDS多种格式
- ✅ 自动化流程: 一键转换,自动生成可视化脚本
- ✅ 质量验证: 内置数据完整性检查
h5ad_to_seurat_converter.py- 主转换脚本create_seurat_from_csv.R- CSV到RDS转换脚本convert_h5ad_to_rds.R- 直接h5ad到RDS转换脚本
# 必需包
pip install scanpy pandas numpy anndata scipy h5py
# 可选包(用于进度显示)
pip install tqdm# 必需包
install.packages(c("Seurat", "dplyr", "ggplot2", "Matrix"))
# 推荐包(用于h5ad直接读取)
remotes::install_github("mojaveazure/seurat-disk")# 步骤1: Python转换为CSV格式
python h5ad_to_seurat_converter.py your_data.h5ad -o output_dir -p data_name
# 步骤2: R转换为RDS格式
Rscript create_seurat_from_csv.R \
output_dir/data_name_metadata.csv \
output_dir/data_name_umap.csv \
output_dir/data_name_pca.csv \
data_name# 直接转换(需要SeuratDisk)
Rscript convert_h5ad_to_rds.R your_data.h5ad output_prefixpython h5ad_to_seurat_converter.py input.h5adpython h5ad_to_seurat_converter.py input.h5ad \
--output_dir custom_output \
--prefix experiment_name \
--rds # 尝试直接创建RDS(实验性功能)input.h5ad: 输入的h5ad文件路径-o, --output_dir: 输出目录(默认: seurat_conversion)-p, --prefix: 输出文件前缀(默认: converted_data)--rds: 尝试直接创建RDS文件(需要R环境)--check-deps: 检查Python依赖
prefix.h5ad- 优化的h5ad文件prefix_metadata.csv- 细胞元数据prefix_gene_metadata.csv- 基因元数据prefix_umap.csv- UMAP坐标prefix_pca.csv- PCA坐标prefix_load_seurat.R- R加载脚本
Rscript create_seurat_from_csv.R metadata.csv umap.csv pca.csv output_prefix参数说明:
metadata.csv: 细胞元数据文件umap.csv: UMAP坐标文件pca.csv: PCA坐标文件output_prefix: 输出文件前缀
输出文件:
output_prefix_seurat.rds- Seurat对象output_prefix_summary.txt- 对象摘要output_prefix_load_and_plot.R- 加载和可视化脚本
Rscript convert_h5ad_to_rds.R input.h5ad output_prefix# 使用批量处理脚本
python example_workflow.py或创建自定义批量脚本:
import subprocess
import sys
datasets = [
{"input": "data1.h5ad", "prefix": "experiment1"},
{"input": "data2.h5ad", "prefix": "experiment2"}
]
for dataset in datasets:
# Python转换
subprocess.run([
sys.executable, "h5ad_to_seurat_converter.py",
dataset["input"], "-p", dataset["prefix"]
])
# R转换
subprocess.run([
"Rscript", "create_seurat_from_csv.R",
f"seurat_conversion/{dataset['prefix']}_metadata.csv",
f"seurat_conversion/{dataset['prefix']}_umap.csv",
f"seurat_conversion/{dataset['prefix']}_pca.csv",
dataset["prefix"]
])# 转换testis单细胞数据
python h5ad_to_seurat_converter.py \
scanpypipline_output/adata_cellAnno.h5ad \
-o testis_seurat \
-p testis_annotated
# 创建RDS对象
Rscript create_seurat_from_csv.R \
testis_seurat/testis_annotated_metadata.csv \
testis_seurat/testis_annotated_umap.csv \
testis_seurat/testis_annotated_pca.csv \
testis_annotated# 加载Seurat对象
library(Seurat)
library(ggplot2)
seurat_obj <- readRDS("testis_annotated_seurat.rds")
# 基本信息
print(seurat_obj)
table(seurat_obj@meta.data$celltype)
# 可视化
p1 <- DimPlot(seurat_obj, reduction = "umap", group.by = "celltype") +
ggtitle("Cell Types")
p2 <- DimPlot(seurat_obj, reduction = "umap", group.by = "sample") +
ggtitle("Samples")
# 保存图片
ggsave("celltype_umap.pdf", p1, width = 12, height = 8)
ggsave("sample_umap.pdf", p2, width = 12, height = 8)
# 质控可视化
VlnPlot(seurat_obj,
features = c("nFeature_RNA", "nCount_RNA", "pct_counts_mt"),
group.by = "celltype")# 检查Python依赖
python h5ad_to_seurat_converter.py --check-deps
# 检查输入文件
python -c "
import scanpy as sc
adata = sc.read_h5ad('your_data.h5ad')
print(f'Cells: {adata.n_obs}, Genes: {adata.n_vars}')
print(f'Metadata: {list(adata.obs.columns)}')
print(f'Embeddings: {list(adata.obsm.keys())}')
"# 在R中验证
seurat_obj <- readRDS("output_seurat.rds")
# 检查基本信息
print(seurat_obj)
cat("Cells:", ncol(seurat_obj), "\n")
cat("Genes:", nrow(seurat_obj), "\n")
cat("Reductions:", names(seurat_obj@reductions), "\n")
# 检查元数据完整性
cat("Metadata columns:", ncol(seurat_obj@meta.data), "\n")
if ("celltype" %in% colnames(seurat_obj@meta.data)) {
cat("Cell types:", length(unique(seurat_obj@meta.data$celltype)), "\n")
}# 运行测试套件
python test_converter.py- 小数据集 (<10k细胞): 支持完整CSV导出
- 大数据集 (>10k细胞): 自动使用稀疏格式,跳过大型CSV导出
- 超大数据集 (>100k细胞): 建议使用子集或分批处理
- 基因名称: 自动处理重复基因名,下划线替换为连字符
- 细胞ID: 保持原始细胞条形码
- 元数据: 完整保留所有列,自动处理缺失值
- SeuratDisk无法读取h5ad: 使用CSV方法转换
- 内存不足: 减少基因数量或使用分批处理
- R包缺失: 确保安装所有必需的R包
- 路径问题: 使用绝对路径或确保工作目录正确
# 依赖问题
pip install --upgrade scanpy pandas numpy anndata
# 内存错误
# 减少数据大小或增加系统内存# 包安装问题
install.packages(c("Seurat", "dplyr", "ggplot2", "Matrix"))
# SeuratDisk问题
remotes::install_github("mojaveazure/seurat-disk")# 检查数据完整性
import scanpy as sc
adata = sc.read_h5ad('data.h5ad')
adata.var_names_make_unique() # 处理重复基因名
adata.obs.fillna('Unknown', inplace=True) # 处理缺失值# 在Python中预处理,只保留高变基因
import scanpy as sc
adata = sc.read_h5ad('input.h5ad')
# 选择高变基因
if 'highly_variable' in adata.var.columns:
adata_hvg = adata[:, adata.var['highly_variable']].copy()
else:
sc.pp.highly_variable_genes(adata, n_top_genes=3000)
adata_hvg = adata[:, adata.var['highly_variable']].copy()
# 保存子集
adata_hvg.write('input_hvg.h5ad')# 处理多个样本的脚本
#!/bin/bash
for sample in sample1 sample2 sample3; do
echo "Processing $sample..."
python h5ad_to_seurat_converter.py \
data/${sample}.h5ad \
-o results/${sample} \
-p ${sample}
Rscript create_seurat_from_csv.R \
results/${sample}/${sample}_metadata.csv \
results/${sample}/${sample}_umap.csv \
results/${sample}/${sample}_pca.csv \
${sample}
done# 在R中整合多个转换后的对象
library(Seurat)
# 加载多个RDS文件
obj1 <- readRDS("sample1_seurat.rds")
obj2 <- readRDS("sample2_seurat.rds")
obj3 <- readRDS("sample3_seurat.rds")
# 合并对象
combined_obj <- merge(obj1, y = c(obj2, obj3),
add.cell.ids = c("S1", "S2", "S3"))
# 保存合并后的对象
saveRDS(combined_obj, "combined_seurat.rds")# 创建质量检查报告
assess_conversion_quality <- function(rds_file, original_csv) {
library(Seurat)
library(dplyr)
# 加载数据
seurat_obj <- readRDS(rds_file)
original_meta <- read.csv(original_csv, row.names = 1)
# 检查细胞数量
cat("=== 数据完整性检查 ===\n")
cat("原始细胞数:", nrow(original_meta), "\n")
cat("转换后细胞数:", ncol(seurat_obj), "\n")
cat("细胞保留率:", round(ncol(seurat_obj)/nrow(original_meta)*100, 2), "%\n\n")
# 检查元数据列
cat("=== 元数据检查 ===\n")
cat("原始元数据列数:", ncol(original_meta), "\n")
cat("转换后元数据列数:", ncol(seurat_obj@meta.data), "\n")
# 检查细胞类型分布
if ("celltype" %in% colnames(seurat_obj@meta.data)) {
cat("\n=== 细胞类型分布 ===\n")
print(table(seurat_obj@meta.data$celltype))
}
# 检查降维结果
cat("\n=== 降维结果 ===\n")
cat("可用降维:", names(seurat_obj@reductions), "\n")
return(seurat_obj)
}
# 使用示例
assess_conversion_quality("testis_seurat.rds", "original_metadata.csv")| 数据集大小 | 细胞数 | 基因数 | Python转换时间 | R转换时间 | RDS文件大小 |
|---|---|---|---|---|---|
| 小型 | 1,000 | 2,000 | 5秒 | 10秒 | 2MB |
| 中型 | 10,000 | 5,000 | 30秒 | 45秒 | 15MB |
| 大型 | 50,000 | 10,000 | 2分钟 | 3分钟 | 60MB |
| 超大型 | 100,000+ | 20,000+ | 5分钟+ | 8分钟+ | 150MB+ |
# 对于大数据集,设置R内存限制
R --max-ppsize=500000 --max-mem-size=32G
# 或在R中设置
options(expressions = 500000)
memory.limit(size = 32000) # Windows# 在转换前添加自定义注释
import pandas as pd
import scanpy as sc
adata = sc.read_h5ad('input.h5ad')
# 添加自定义分组
adata.obs['custom_group'] = ['Group1' if 'TH' in x else 'Group2'
for x in adata.obs['sample']]
# 添加年龄分组
adata.obs['age_group'] = pd.cut(adata.obs['age'],
bins=[0, 10, 15, 20],
labels=['Young', 'Middle', 'Old'])
# 保存修改后的数据
adata.write('input_annotated.h5ad')# 创建高级可视化脚本
create_advanced_plots <- function(seurat_obj, output_prefix) {
library(Seurat)
library(ggplot2)
library(patchwork)
# 1. 多面板UMAP图
p1 <- DimPlot(seurat_obj, group.by = "celltype") + ggtitle("Cell Types")
p2 <- DimPlot(seurat_obj, group.by = "sample") + ggtitle("Samples")
p3 <- DimPlot(seurat_obj, group.by = "group") + ggtitle("Groups")
p4 <- FeaturePlot(seurat_obj, features = "nFeature_RNA") + ggtitle("Gene Count")
combined <- (p1 | p2) / (p3 | p4)
ggsave(paste0(output_prefix, "_comprehensive_umap.pdf"),
combined, width = 16, height = 12)
# 2. 质控指标小提琴图
qc_plot <- VlnPlot(seurat_obj,
features = c("nFeature_RNA", "nCount_RNA", "pct_counts_mt"),
group.by = "celltype", ncol = 3)
ggsave(paste0(output_prefix, "_qc_violin.pdf"),
qc_plot, width = 18, height = 6)
# 3. 样本组成条形图
composition <- seurat_obj@meta.data %>%
count(celltype, sample) %>%
ggplot(aes(x = celltype, y = n, fill = sample)) +
geom_bar(stat = "identity", position = "fill") +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(title = "Cell Type Composition by Sample", y = "Proportion")
ggsave(paste0(output_prefix, "_composition.pdf"),
composition, width = 12, height = 8)
}
# 使用示例
seurat_obj <- readRDS("testis_seurat.rds")
create_advanced_plots(seurat_obj, "testis_analysis")