基因表达数据的预处理是后续差异分析、降维可视化的核心前提 ,其目标是:去除噪声、统一量纲、纠正系统偏差(如批次效应)、处理缺失/异常值,确保数据满足统计分析的要求。MATLAB中需结合基因表达数据的特性(高维、稀疏、分微阵列/RNA-seq类型),按标准化流程处理,以下是完整可复现的预处理步骤、代码及关键解读。
一、预处理核心目标与数据类型区分
1. 核心目标
- 过滤无生物学意义的低表达基因(减少噪声和计算量);
- 消除量纲差异(如不同基因表达量范围差异达数个数量级);
- 处理缺失值/异常值(避免统计检验偏差);
- 校正批次效应(多批次实验数据的系统误差);
- 转换数据分布(如RNA-seq计数数据的对数转换)。
2. 常见数据类型(预处理方法差异大)
| 数据类型 | 特征 | 预处理重点 |
|---|---|---|
| 微阵列数据 | 连续型、易受芯片效应影响 | 分位数标准化、批次校正 |
| RNA-seq原始计数数据 | 离散型(读段数)、高稀疏性 | 低计数过滤、TMM/RLE归一化、log2转换 |
| RNA-seq标准化数据(FPKM/TPM) | 连续型、已校正测序深度 | z-score标准化、低表达过滤 |
二、标准预处理流程(附MATLAB代码)
以下以"混合模拟数据"为例,覆盖微阵列/RNA-seq的通用预处理流程,可直接适配真实数据。
步骤1:数据加载与格式转换
首先加载数据(支持GEO下载的.txt/.csv、矩阵格式、表格格式),并转换为"样本×基因"的矩阵(行=样本,列=基因)。
matlab
% ===================== 1.1 加载数据(二选一) =====================
% 选项1:加载真实数据(GEO下载的txt/csv)
% data_table = readtable('GSE12345_expr.txt', 'TextType','string'); % 第一列=样本名,后续列=基因
% group = categorical(data_table(:,1)); % 分组标签(可选)
% expr_matrix = table2array(data_table(:,2:end)); % 表达矩阵 [样本数×基因数]
% 选项2:模拟数据(复现用,模拟RNA-seq计数+微阵列混合特征)
rng(1);
n_samples = 60; % 60个样本(20 Control + 40 Treatment)
n_genes = 2000; % 2000个基因
% 模拟RNA-seq原始计数(离散、高稀疏)
expr_counts = randi([0, 1000], n_samples, n_genes);
% 模拟微阵列数据(连续、正态分布)
expr_array = randn(n_samples, n_genes) * 50 + 100;
% 分组标签
group = categorical([repmat('Control',20,1); repmat('Treatment',40,1)]);
% 人为添加缺失值和异常值(模拟真实数据)
expr_counts(randi(n_samples*n_genes, 50,1)) = NaN; % 50个缺失值
expr_array(randi(n_samples*n_genes, 30,1)) = expr_array(randi(n_samples*n_genes, 30,1)) * 10; % 异常值
步骤2:数据质控(QC)------ 检测异常样本/基因
质控是预处理的"第一道关卡",通过可视化识别异常样本(如离群值、批次偏差),避免后续分析偏差。
matlab
% ===================== 2.1 样本水平QC(箱线图:检测整体表达分布) =====================
figure('Color','w');
tiledlayout(1,2);
% 计数数据QC
nexttile;
boxplot(log2(expr_counts+1)); % log2转换后可视化(避免0值)
title('RNA-seq计数数据样本表达分布');
xlabel('样本'); ylabel('log2(Count+1)');
% 微阵列数据QC
nexttile;
boxplot(expr_array);
title('微阵列数据样本表达分布');
xlabel('样本'); ylabel('表达量');
% ===================== 2.2 样本相关性分析(检测离群样本) =====================
% 计算样本间皮尔逊相关系数
corr_matrix = corr(expr_array, 'Rows','pairwise'); % 忽略缺失值
figure('Color','w');
heatmap(corr_matrix, 'Colormap',parula, 'Title','样本间相关性热图');
% 识别离群样本(相关性<0.5的样本)
mean_corr = mean(corr_matrix, 2);
outlier_samples = mean_corr < 0.5;
fprintf('检测到 %d 个离群样本\n', sum(outlier_samples));
% 移除离群样本(可选,根据研究需求)
expr_array(outlier_samples, :) = [];
expr_counts(outlier_samples, :) = [];
group(outlier_samples, :) = [];
步骤3:过滤低表达基因(核心!减少噪声)
低表达基因(如RNA-seq中大部分样本count=0)无生物学意义,会增加计算量和假阳性,需优先过滤。
matlab
% ===================== 3.1 RNA-seq原始计数数据过滤 =====================
% 规则:至少10%的样本count≥5(可调整,如严格版:20%样本count≥10)
filter_counts = mean(expr_counts >= 5, 1) >= 0.1; % 列(基因)维度计算
expr_counts_filtered = expr_counts(:, filter_counts);
fprintf('RNA-seq过滤后剩余基因数:%d/%d\n', sum(filter_counts), n_genes);
% ===================== 3.2 微阵列/标准化RNA-seq数据过滤 =====================
% 规则:至少80%样本表达量>0.1(消除背景噪声)
filter_array = mean(expr_array > 0.1, 1) >= 0.8;
expr_array_filtered = expr_array(:, filter_array);
fprintf('微阵列过滤后剩余基因数:%d/%d\n', sum(filter_array), n_genes);
步骤4:标准化/归一化(消除系统偏差)
核心是统一数据量纲,不同数据类型对应不同方法:
| 数据类型 | 推荐方法 | 适用场景 |
|---|---|---|
| 微阵列数据 | 分位数标准化(Quantile) | 消除芯片间系统偏差 |
| RNA-seq原始计数 | TMM/RLE归一化 | 校正测序深度和基因长度偏差 |
| 所有类型(后续分析用) | z-score标准化 | 消除基因间量纲差异,适配统计检验 |
matlab
% ===================== 4.1 RNA-seq计数数据:TMM归一化(需调用R包edgeR) =====================
% 步骤1:导出计数数据到CSV
writematrix(expr_counts_filtered, 'counts_filtered.csv');
% 步骤2:编写R脚本执行TMM归一化
r_script_tmm = [
'library(edgeR);'
'counts <- read.csv("counts_filtered.csv", header=F);'
'dge <- DGEList(counts=as.matrix(counts));'
'dge <- calcNormFactors(dge, method="TMM");' % TMM归一化
'counts_tmm <- cpm(dge, log=TRUE);' % 转换为log2(CPM)
'write.csv(counts_tmm, "counts_tmm.csv");'
];
% 运行R脚本(需安装edgeR包,MATLAB需配置R环境)
system(['Rscript -e "', r_script_tmm, '"']);
% 步骤3:MATLAB读取归一化后的数据
expr_counts_tmm = readmatrix('counts_tmm.csv');
expr_counts_tmm = expr_counts_tmm(:, 2:end); % 去除行索引列
% ===================== 4.2 微阵列数据:分位数标准化 =====================
expr_array_quantile = quantile_normalize(expr_array_filtered); % 自定义函数
% ===================== 4.3 通用:z-score标准化(适配后续统计分析) =====================
% 对归一化后的数据做z-score(行=样本,列=基因,按列标准化)
expr_counts_std = zscore(expr_counts_tmm, 0, 1);
expr_array_std = zscore(expr_array_quantile, 0, 1);
% 分位数标准化辅助函数
function normalized_data = quantile_normalize(data)
[n, p] = size(data);
% 按列排序
sorted_data = sort(data, 1);
% 计算每行的均值(分位数)
quantile_means = mean(sorted_data, 2);
% 替换原数据的排序值为分位数均值
[~, idx] = sort(data, 1);
normalized_data = zeros(n, p);
for j = 1:p
normalized_data(idx(:,j), j) = quantile_means;
end
end
步骤5:缺失值处理(避免统计偏差)
优先用K近邻填充(KNN)(保留数据分布),避免简单均值/中位数填充(引入偏差)。
matlab
% ===================== 5.1 K近邻填充缺失值(需Statistics Toolbox) =====================
% 处理RNA-seq归一化数据的缺失值
if any(isnan(expr_counts_std))
expr_counts_std = knnimpute(expr_counts_std); % K=5(默认)
end
% 处理微阵列标准化数据的缺失值
if any(isnan(expr_array_std))
expr_array_std = knnimpute(expr_array_std);
end
% ===================== 5.2 异常值处理(可选) =====================
% 方法:将超过3倍标准差的值截断为±3σ(避免极端值影响)
sigma = 3;
expr_counts_std(expr_counts_std > sigma) = sigma;
expr_counts_std(expr_counts_std < -sigma) = -sigma;
expr_array_std(expr_array_std > sigma) = sigma;
expr_array_std(expr_array_std < -sigma) = -sigma;
步骤6:批次效应校正(多批次数据必做)
多批次实验(如不同时间/平台测序)会引入系统偏差,需用ComBat校正(MATLAB调用R包sva)。
matlab
% 模拟批次信息(60样本分2个批次)
batch = categorical([repmat('Batch1',30,1); repmat('Batch2',30,1)]);
% 导出数据和批次信息到CSV
writematrix(expr_array_std, 'array_std.csv');
writetable(table(batch), 'batch_info.csv');
% 编写R脚本执行ComBat校正
r_script_combat = [
'library(sva);'
'data <- read.csv("array_std.csv", header=F);'
'batch <- as.factor(read.csv("batch_info.csv")[,1]);'
'mod <- model.matrix(~1, data=as.data.frame(t(data)));' % 无分组的校正模型
'data_combat <- ComBat(dat=t(data), batch=batch, mod=mod);'
'write.csv(t(data_combat), "array_combat.csv");'
];
% 运行R脚本
system(['Rscript -e "', r_script_combat, '"']);
% 读取校正后的数据
expr_array_combat = readmatrix('array_combat.csv');
expr_array_combat = expr_array_combat(:, 2:end);
步骤7:数据转换(按需)
- RNA-seq计数数据:需
log2(CPM+1)/log2(TPM+1)转换,使数据接近正态分布; - 微阵列数据:若分布偏态,可做
log2转换(需确保无负值)。
matlab
% RNA-seq计数数据log2转换(已在TMM归一化时完成,此处为示例)
expr_counts_log = log2(expr_counts_filtered + 1); % +1避免log2(0)
三、不同数据类型的预处理模板(直接复用)
模板1:微阵列数据预处理
matlab
% 1. 加载数据
data = readtable('array_data.txt');
expr = table2array(data(:,2:end));
% 2. 质控(移除离群样本)
corr_mat = corr(expr, 'Rows','pairwise');
outlier = mean(corr_mat,2) < 0.5;
expr = expr(~outlier, :);
% 3. 过滤低表达基因
filter = mean(expr>0.1,1)>=0.8;
expr = expr(:,filter);
% 4. 分位数标准化
expr = quantile_normalize(expr);
% 5. z-score标准化
expr = zscore(expr,0,1);
% 6. 缺失值填充
expr = knnimpute(expr);
% 7. 批次校正(如有批次)
% ...(参考步骤6)
模板2:RNA-seq原始计数数据预处理
matlab
% 1. 加载数据
counts = readmatrix('counts_data.csv');
% 2. 过滤低表达基因
filter = mean(counts>=5,1)>=0.1;
counts = counts(:,filter);
% 3. TMM归一化+log2转换(调用edgeR)
% ...(参考步骤4.1)
% 4. z-score标准化
counts_std = zscore(counts_tmm,0,1);
% 5. 缺失值填充
counts_std = knnimpute(counts_std);
四、关键注意事项
-
参数选择:
- 低表达过滤阈值:RNA-seq可放宽至"5%样本count≥3"(小样本),微阵列避免过严(否则丢失关键基因);
- KNN填充的K值:默认K=5,高维数据可设K=10;
- 标准化方法:无批次的微阵列用分位数,有批次用ComBat+分位数;RNA-seq优先TMM(优于RLE)。
-
避免常见错误:
- 不要先标准化再过滤低表达基因(噪声基因会干扰标准化);
- 不要用均值填充缺失值(会抹平样本间差异);
- RNA-seq计数数据不要直接做z-score(未校正测序深度)。
-
工具依赖:
- MATLAB需安装:Statistics and Machine Learning Toolbox;
- RNA-seq/TMM/ComBat需调用R包:
edgeR、sva(需配置MATLAB-R联动,参考MATLAB帮助文档)。
五、预处理后的数据验证
预处理完成后,需验证数据质量:
matlab
% 1. 箱线图:验证样本表达分布是否一致
boxplot(expr_array_combat);
title('批次校正后样本表达分布');
% 2. 主成分分析(PCA):验证批次是否被消除
[~, score] = pca(expr_array_combat);
gscatter(score(:,1), score(:,2), batch); % 批次标签着色,若无聚类则校正成功
如需针对单细胞RNA-seq、空间转录组等特殊类型基因表达数据的预处理(如细胞过滤、归一化方法SCTransform),可补充说明,我会定制化调整代码!