数据准备误区:忽略数据标准化、不处理缺失值、数据范围不一致导致视觉偏差
做图表最怕什么?数据还没准备好,就急着出图。我在项目里见过太多人,拿到数据点几下鼠标就扔进工具里生成堆叠图、热力图……结果图是出来了,但里面的坑一个比一个深。今天咱们专门聊聊数据准备阶段的三个常见误区,说白了就是:没标准化、没处理缺失值、数据范围没对齐。
这三个问题如果没解决,丰度图表基本就是废的。视觉上可能好看,但结论全是错的。我自己踩过不少坑,后来总结了一套排查方法,咱们一个一个说。
误区一:忽略数据标准化
丰度数据经常来自不同批次、不同实验或不同测序深度。直接拿原始值画图,相当于把苹果和橙子放在一起比重量——根本没法比。
举个例子:A样品测序深度100万条reads,B样品只有20万条。A样品里某个丰度值500,B样品里某个丰度值100。单看数值,A是B的5倍。但标准化之后(比如每百万条reads的丰度),A可能是500,B可能是500。完全不一样。这就是没标准化的后果。
我个人习惯,拿到数据第一件事就是问:这个丰度值,是原始值还是已经标准化过了?如果没有,马上做标准化。
常用标准化方法
| 方法 | 适用场景 | 说明 |
|---|---|---|
| CPM (Counts Per Million) | RNA-seq、scRNA-seq | 每百万reads中的count数,消除测序深度差异 |
| TPM (Transcripts Per Million) | 转录组定量 | 结合基因长度和测序深度,更准确 |
| RPKM/FPKM | 基因表达 | 每百万reads每千碱基,注意方向性 |
| 分位数归一化 | 多组比较 | 使多个样品的分布一致,消除批次效应 |
| Z-score | 热力图、聚类 | 均值0,标准差1,突出相对变化 |
我遇到过最典型的案例:某个项目做了宏基因组分析,不同样本的测序深度差了一个数量级。同事直接拿原始计数做堆叠柱状图,看着A样品里某个菌占60%,B样品里占10%。其实标准化后,两个样品那个菌的比例都是15%左右。嗯,那次被审稿人直接问住,后来再也不敢跳过标准化了。
误区二:不处理缺失值
丰度数据里缺失值非常常见——有些物种在部分样本里没检测到,某些基因在特定条件下不表达。但很多工具和脚本遇到缺失值就报错,或者默默把它当成0处理。这就出大问题了。
我曾经排查过一个散点图,发现某组数据有好多点在零点附近密集分布。查了半天,原来是缺失值被填充成了0。实际上这些点应该是“无数据”,而不是“丰度为0”。这俩完全是两码事。
处理缺失值的常见方式
- 直接删除:如果缺失比例小(<5%),可以整行或整列删除。但小心别把关键样本删了。
- 填充为0:适用于明确表示“未检测到”的场景。但必须标注清楚。
- 填充为极小值:比如用最小检测限的一半。适合后续做log转换,避免-Inf。
- 插值填充:用均值、中位数、或邻近值填补。适合连续变量,但会引入偏差。
- 保留为NA:一些可视化工具支持跳过NA,比如ggplot2的
na.rm=TRUE。
sum(is.na(data)) 看看还有多少NA。如果真的必须填充,我用一个突出颜色标注填充点(比如在散点图上用不同颜色标记填充值),这样观众知道这些点的数据是推算的。
代码示例:检查并处理缺失值
# R语言示例
# 检查每列的缺失值数量
colSums(is.na(abundance_data))
# 如果缺失<5%,直接删除对应行
cleaned_data <- na.omit(abundance_data)
# 如果需要填充为极小值(比如1e-6)
min_val <- min(abundance_data[!is.na(abundance_data)], na.rm = TRUE) / 10
cleaned_data[is.na(abundance_data)] <- min_val
# 绘图时跳过NA
ggplot(cleaned_data, aes(x = sample, y = abundance)) +
geom_point(na.rm = TRUE) # 注意这个参数
误区三:数据范围不一致导致视觉偏差
这个坑特别隐蔽。假设有两组丰度数据:A组0~1000,B组0~1。你如果直接画在同一个坐标轴上,B组的数据几乎会压缩成一条线,根本看不到细节。反过来,如果使用不同的缩放尺度,又可能误判组间差异。
我记得有次做降维后的散点图,两个主成分解释方差差了一个数量级。我没做缩放,直接画出来,点的分布完全是扁的。后来用了scale()标准化之后,才看出真正的聚类结构。
常见的范围不一致情况
- 不同技术平台:qPCR vs RNA-seq,数值范围差好几个数量级。
- 不同批次:实验条件细微差异导致整体偏移。
- 不同数据类型:绝对丰度 vs 相对比例,数值尺度完全不同。
- 不同样本类型:组织样本 vs 细胞样本,含量差异大。
排查表格:如何判断数据范围是否一致
| 检查项 | 方法 | 异常信号 |
|---|---|---|
| 总体范围 | range(data) | 最小值/最大值相差几个数量级 |
| 每列的范围 | 每列的min/max | 某列最大值为另一列的100倍以上 |
| 每行的范围 | 按行统计最大值/最小值 | 存在极端离群值导致其余值被压扁 |
| 变异系数 | 每列 CV = sd/mean | CV 超过 100%(即 sd > mean) |
那怎么解决呢?简单说:统一尺度。常用的方法有:
- 缩放到[0,1]区间:
(x - min(x)) / (max(x) - min(x)) - Z-score标准化:
(x - mean(x)) / sd(x) - 对于丰度数据,log转换很常用:
log2(x + 1)可以压缩大值,放大小值的差异。
数据准备阶段的核心流程
我整理了一个流程图,把上面三个误区串起来。每次做图前按这个走一遍,能避免80%的坑。
这张图总结了我每次做丰度图之前的检查流程。先处理缺失值,再检查数据范围是否一致,最后决定用哪种标准化方法。你想想看,大部分坑都是因为跳过了其中某一步。按这个流程走,至少能保证数据本身没问题。