表观遗传时钟计算器
从 beta 值文件中计算 DNA 甲基化衰老时钟。提供 25 种时钟;GrimAge 是核心时钟。
自包含。 仅需 pandas + numpy——无需 biolearn、torch、seaborn、scipy 或 network。时钟系数和参考文献已嵌入在 data/ 目录下(从开源的 biolearn 库中提取,并精简为时钟实际使用的 CpG 位点,总计约 1 MB)。scripts/compute_clocks.py 忠实地重新实现了 biolearn 的 GrimageModel、LinearMethylationModel 以及 DunedinPACE 的分位数归一化(使用仅依赖 numpy 的 rankdata),可重现 biolearn 对所有 25 种时钟的输出(经验证差异小于 0.005,即仅舍入误差)。
时钟列表(运行 --list-clocks 获取最新列表)
| 家族 | 时钟 | 单位 |
|---|---|---|
| GrimAge(第二代,死亡率相关) | grimagev1, grimagev2 | 年 (需要年龄+性别) |
| 第一代 时间年龄相关 | horvath, horvath2, hannum, lin, vidalbralo, weidner, garagnani, bocklandt | 年 |
| 第二代 生物学年龄相关 | phenoage, hrsinchphenoage | 年 |
| Ying 2022(因果关系) | yingcausage, yingdamage, yingadaptage | 年 |
| 随机性 | stoch, stocp, stocz | 年 |
| 组织特异性 | pedbe(儿科口腔黏膜), cortical(大脑) | 年 |
| 第三代 衰老速度相关 | dunedinpace, dunedinpoam | 年/年 |
| 其他标记物 | dnamtl(端粒长度 kb), zhang(死亡率), epitoc1(有丝分裂) | 各异 |
--clocks 的分组别名:all、grimage、core(默认)、firstgen、secondgen、thirdgen。
dunedinpace 需要约 20k 个背景 CpG 位点 用于其分位数归一化(不仅仅是其 173 个模型 CpG 位点)。在稀疏输入上,它会从金标准参考中自我推算缺失的背景 CpG;如果报告的覆盖率远低于约 90%,则结果主要由参考数据主导,不可靠——请如此说明。完整的 EPIC/450K 导出数据可完美覆盖。
关于 GrimAge 的关键事实(以便正确解读)
GrimAge 是第二代、基于死亡率训练的:它估计 7 种血浆蛋白的 DNAm 替代标记物 + 吸烟包年数(V2 增加了 DNAm A1C 和 CRP),然后与实际年龄和性别一起纳入生存模型。年龄和性别直接进入公式,因此任何 grimage* 时钟都需要这两个参数。其他时钟不需要它们,但传递 --age 参数可以让工具报告加速值。
工作流程
1. 检查输入文件
自动检测的布局:长格式(两列:CpG ID + beta 值)或矩阵格式(第一列 CpG ID,其余列 = 样本)。Beta 值在 [0,1] 范围内的浮点数。注意行数;每个时钟的 CpG 覆盖率会逐个报告。
2. 获取年龄和性别
GrimAge 需要。如果只知道年龄范围,请使用中位数并运行 --sensitivity 参数,以便用户观察结果对具体年龄的依赖程度。
3. 检查依赖项(仅 pandas + numpy)
python3 -c "import pandas, numpy" 2>/dev/null && echo OK || pip install pandas numpy
无需 venv、biolearn、torch 或网络。
4. 运行
python3 <skill-dir>/scripts/compute_clocks.py \
--input "<betas.csv>" --age <years> --sex <m|f> \
--clocks all # 或:core(默认)、grimage、firstgen、secondgen 或特定键
# --sensitivity 40 42 47 49 # 可选,当确切年龄不确定时使用
python3 <skill-dir>/scripts/compute_clocks.py --list-clocks # 查看所有键
该脚本会从附带的(精简后的)data/sesame_450k_median.csv 群体参考中推算任何缺失的时钟 CpG 位点,运行每个模型,并打印出数值、加速值(对于以年为单位的时钟)和覆盖率的表格,以及一行 JSON 供下游使用。
5. 报告与解读
首先报告 GrimAge,然后进行比较。始终传达以下注意事项:
- 开源重新实现,非官方计算器。 数值与 Horvath 官方服务器 / Clock Foundation 非常接近,但不是认证数字。如需可引用的数值,请指向 Horvath DNAm Age 计算器或商业提供商。
- 此处的“加速值” = 时钟预测年龄 − 实际年龄,一个简单的差值。学术上的 AgeAccel(与同龄人群的残差)需要群体样本,无法为单个人计算——因此 +8 意味着“表观遗传预测年龄比实际年龄大 8 岁”,而非“比同龄人大 8 岁”。
- 各代次不同。 第一代(Horvath/Hannum/Lin/…)旨在预测实际年龄,通常接近真实年龄。第二代(GrimAge/PhenoAge)旨在预测健康结果,对死亡率和衰老的预测效果更好——设计上会与实际年龄存在差异。不要将 GrimAge 解读为“看起来像 N 岁”;它是一个以年为单位表示的风险评分。
- 非年份时钟(
dunedinpoam衰老速度、dnamtl端粒长度 kb、zhang/stocz死亡风险、epitoc1有丝分裂)不是年龄——不显示加速值。 - 覆盖率/推算:用群体中位数填充少量缺失的时钟 CpG 是正常的;对于覆盖率低于约 90% 的时钟请标记。输出中的
n_lowconf列统计了血液参考标准差 > 0.08(填充需谨慎)的推算 CpG 数量——这是比单纯覆盖率更细致的位点级别信号。一个有很多n_lowconf填充的时钟,即使“运行成功”,在这个样本上也是不可靠的。 - 仅限血液设计。 此技能假设为人类全血。时钟应用于血液;推算参考也是血液数据。请勿用于其他组织。
- 缺失 CpG 的推算——默认使用 methyLImp。 缺失的时钟 CpG(例如 EPIC 训练的 CpG 在 MSA/WeGene 导出中缺失)通过 methyLImp 进行推算:一种降秩(PCA)回归方法,利用样本观测到的 CpG 位点,基于全血面板的 CpG 间相关性结构来预测每个缺失的 CpG——比简单使用中位数更准确(当组织匹配时 RMSE 降低约 30%)。面板中缺失的 CpG 则回退到血液中位数;
n_lowconf(血液 SD > 0.08)标记不可靠的填充。运行开始时将打印当前使用的模式。- 面板文件位于
data/blood_panel.npz,已随技能打包(约 5 MB;基于 GSE40279 构建,包含 656 个全血 450K 样本,精简为时钟 CpG 位点 + 50 个血液主成分 + 每个 CpG 的中位数/SD)。因此 methyLImp 开箱即用——在预留 CpG 基准测试中,与简单中位数相比,推算 RMSE 降低了约 10%。要重建/自定义,请运行scripts/build_blood_panel.py。如果文件丢失,工具将优雅地降级为全局中位数并提示用户。 - 实际提示:methyLImp 主要改善了大量推算的时钟。高覆盖率的时钟(GrimAge/Horvath/PhenoAge)推算的 CpG 很少,因此其值变化小于 0.2 年——置信度标记才是更实用的改进。
- 面板文件位于
- 非医疗建议——仅用于研究/教育目的。
注意事项
- 矩阵输入 → 每个样本每个时钟输出一行结果。
- 故意排除(无法在没有更重依赖的情况下忠实地重现,或非衰老时钟):
- PC 时钟(
PCHorvath…)、AltumAge、GPAge——需要 PCA 旋转/神经网络。 - 孕期时钟(Knight、Lee、Mayne、Bohlin)——用于脐带血/新生儿。
- 性状和疾病预测器(BMI、胆固醇、吸烟、饮酒、阿尔茨海默病、心血管疾病等)——这些是生物标志物模型,而非衰老时钟。 如果用户特别需要其中之一,请告知需要完整安装 biolearn。
- PC 时钟(
- 来源。 系数来自 biolearn(MIT 许可证),它重新实现了已发表的时钟。GrimAge 在化妆品和人寿保险使用方面有商业使用限制(UCLA TDG / Clock Foundation)。