缺失值基础:缺失值定义、表现形式与机制
做质控这行,迟早要跟“缺失值”正面交锋。说白了,缺失值就是数据框里那个空洞——明明是变量本该有的数值,偏偏给你留了个空。我刚开始接触组学数据时,觉得不就是几个空值嘛,删掉不就行了?后来踩的坑多了才明白:缺失值的类型和处理策略,直接决定你后续分析的生死。
缺失值定义与表现形式
先看定义。缺失值是指在数据采集、存储或传输过程中,某个变量的观测值未能被记录或记录为无效。在数据表里,它可能长这样:
- NaN —— Python 里最常见的缺失标记,属于 float 类型。
- None —— Python 对象级别的空值,常见于异构数据。
- NA —— R 语言的标准缺失符,Pandas 内部也用它表示。
- 空字符串 '' —— 文本列容易出现的伪缺失,需要单独处理。
- 特殊占位符 —— 比如 -999、0、9999,我常在旧版质谱数据里碰到。
df.fillna(0) 把原始 0 也填了,结果下游分析全部偏移。一定要先确认你的缺失标识。实际项目中,我习惯用一行代码快速摸清缺失分布:
import pandas as pd
df = pd.read_csv("qc_data.csv")
# 看看每一列有多少缺失
print(df.isnull().sum())
# 缺失比例
print(df.isnull().mean().round(4) * 100)
这段代码会输出类似这样:
sample_id 0
intensity_A 23
intensity_B 45
intensity_C 8
dtype: int64
intensity_A 12.50
intensity_B 25.00
intensity_C 4.44
dtype: float64
看到 25% 的缺失率,你第一反应是什么?不能直接删,也不能随便插补。得先搞清楚丢失的机制。
缺失机制三兄弟:MCAR、MAR、MNAR
我不喜欢背教科书定义,但这三个概念实在太关键了。它们决定了你的缺失值处理方法是否合理。简单说:
| 机制 | 全称 | 一句话解释 | 举例(组学场景) |
|---|---|---|---|
| MCAR | 完全随机缺失 | 缺失与否跟任何变量都没关系 | 样品瓶标签意外脱落 |
| MAR | 随机缺失 | 缺失概率依赖于其他观测变量 | 低丰度蛋白更易缺失 |
| MNAR | 非随机缺失 | 缺失概率与缺失值本身有关 | 信号低于检测限 |
你想想看,如果数据是 MCAR,那么删除缺失行你基本不引入偏差——但组学数据里这种情况少之又少。我个人经验是:80% 以上的组学缺失属于 MAR 或 MNAR。
我当年做一个蛋白质组项目,用简单均值插补处理所有缺失,结果差异蛋白筛选出来全是假阳性。后来一查:那些缺失最多的蛋白其实是丰度极低的,属于 MNAR,均值插补把它们的均值拉高了,导致很多都被错误地当作上调蛋白。教训深刻。
如何判断缺失机制?实际很难完全断定,但有几个实践经验:
- 对比缺失组与完整组在其他变量上的分布(t 检验或卡方)。如果无显著差异,偏向 MCAR。
- 如果某变量的缺失率与另一个变量高度相关(比如缺失率随样本采集批次变化),大概率是 MAR。
- 如果缺失值出现在极端值附近(比如仪器检测下限),强烈怀疑 MNAR。
缺失值在组学数据中的普遍性
聊点真实的。组学数据(蛋白质组、代谢组、转录组、微生物组)天生就有大量缺失。原因很直白:
- 检测灵敏度限制:低于仪器的定量下限,直接报 NaN。
- 样本降解或污染:部分肽段/代谢物没测到。
- 比对/拼接失败:低表达转录本可能被过滤掉。
- 批次效应:不同批次实验条件波动导致部分通道缺失。
比例能到多高?我接触过的项目中:
- 无标记定量蛋白质组:通常 20%–50% 的蛋白存在至少一个缺失。
- 靶向代谢组:缺失率相对低,5%–15%。
- 单细胞转录组:缺失率可以高达 90%——这就是著名的"dropout"问题。
嗯,这里要特别提醒:缺失值比例不是越低越好。我见过有人为了消除缺失,把所有检测到一次的信号都保留,结果噪声比信号还大。缺失值比例和质量得分需要平衡——这正是本课程后面章节要深挖的核心。
这张图把缺失机制的关系和组学普遍性串起来了。你看,从根节点出发,三个分支指向不同策略。最下面那行绿色提示——先做缺失模式分析,再选方法——这句话值得刻在你的质控流程里。
好了,这就是缺失值的基础框架。下次你做质控,面对一列 NaN 时,先问自己三个问题:这是 MCAR、MAR 还是 MNAR?缺失率有多高?集中出现在哪些样品或特征上?想清楚这些,后面的工作才有意义。