心跳只剩时间戳 — CAST RR 间期子研究库

809 人 / 1543 条 24 小时注释 / 1.5 亿 RR

来源 https://physionet.org/content/crisdb/1.0.0/发布时间: 2026-10-28最后更新: 2026-10-28 阅读 15
心跳只剩时间戳 — CAST RR 间期子研究库

信息速览

数据集名称心跳只剩时间戳 — CAST RR 间期子研究库
数据类型时序信号,人工标注,元数据
规模809 名受试者 / 1543 条记录
接入方式https://physionet.org/content/crisdb/1.0.0/
AI 就绪度

一九八〇年代末,一项被写进教科书的心律失常药物试验得出了一反直觉的结论:把心梗后病人的室性早搏压下去,死亡反而增加。试验因此提前终止,两个药物组被叫停。这场试验留下的东西通常被记成一条临床教训,很少有人记得它还留下了几十万小时的磁带——而且是同一批人在用药前与用药中各录了一次的那种。

CAST RR 间期子研究库就是从那批磁带里抢救出来的一小部分。华盛顿大学的 Phyllis Stein 从试验的数据协调中心取得带子,挑出用药确实有效、并且坚持用下去的人,把两次记录都做成逐搏注释,2004 年交给 PhysioNet。它最终的形态相当极端:809 名受试者、1543 条记录、每条约 24 小时、累计约 1.5 亿个 RR 间期,而整库里没有一个采样点。

这意味着它是一件用途很窄但很难替代的工具。窄到什么程度:你想要波形,一点都没有;你想要频域指标,六成记录不可靠;你想拿它代表普通人群,它是心梗后、频发早搏、还对药物有反应的一小撮人。难替代到什么程度:公开数据里,同一个人、同一套生活节律、跨一次长期用药的两次 24 小时逐搏记录,几乎找不出第二份。一屏速览见下表。

维度 内容
全名 CAST RR Interval Sub-Study Database
俗称与目录名 crisdb(易被误读为 CRISPR 相关,实际指 CAST)
发布方 PhysioNet(原始数据由 NHLBI 支持的 CAST 试验产生)
整理者 Phyllis Stein,华盛顿大学医学院,圣路易斯
首次发布 2004 年 7 月 2 日,版本 1.0.0
受试者数 809 名
记录数 1,543 条
配对结构 734 人各有用药前与用药中两条;其余仅有单条
每条时长 约 24 小时
累计心搏 约 1.5 亿个 RR 间期
信号内容 无。仅有逐搏注释与头文件
文件格式 WFDB:.hea 头文件 + .atr 注释 + RECORDS 清单
时间基准 头文件声明 128 Hz,个别记录重标定为 125.44 Hz
分组 e=恩卡尼,f=氟卡尼,m=莫雷西嗪
记录名 dnnnx:药物字母 + 三位编号 + a(基线)/b(用药中)
许可 ODC-BY 1.0,免注册
整库体积 未压缩约 615 MB
DOI 10.13026/C25P42

§1 它要解决的具体麻烦

1.1 心率变异性研究缺的从来不是算法,是同一个人用药前后的对照

想回答"抗心律失常药会不会改变心率变异性",最干净的设计是同一个人的自身对照:用药前录一天,用药稳定后再录一天,其余条件尽量不变。这个设计在纸面上简单,在现实里几乎无法执行,因为它同时要求三件稀缺事——一批需要长期服这类药的患者、两次各 24 小时的 Holter、以及一次能把药物真正吃下去且确实起效的干预。

前瞻性做这件事在今天已经不可能。恩卡尼与氟卡尼因死亡率问题在 1989 年被叫停,莫雷西嗪在 CAST-II 里同样因死亡率趋势提前终止,这三个药再也没有机会进入这种规模的新试验。也就是说,这个对照设计只存在于历史里,只能靠回溯抢救。

抢救出来的东西就长成了这个库的样子:配对、长时程、逐搏,但没有波形。取舍很明确——当年保存磁带本体的成本高,做注释的成本相对低,而子研究要回答的问题是时间域的心率变异性,用注释就够。于是波形被舍弃,注释被留下。这个取舍决定了今天所有能用与不能用的边界。

1.2 三条常见的错误期待

第一条,期待它是"又一个 Holter 波形库"。它的记录里零条信号通道,头文件第一行就写着 0 个信号、0 个采样点。用 wfdb.rdrecord 去读会直接报错,能读的只有 rdann。很多人第一次下载后以为文件损坏,实际是这份数据本来就只有一层注释。

第二条,期待它是"CAST 全队列的缩影"。CAST 主试验入组三千五百余人,本库只有 809 人,而且是从中再筛过的:用药有效、首次尝试即把早搏压下去八成以上、并且坚持用同一种药。这是疗效筛选之后的人群,不是随机样本,更不是"心梗后人群"的代表样本。

第三条,期待它"既然是 RR 间期,就能直接算 LF/HF"。频域指标要求时间轴足够准,而这批磁带里约六成录制时没有校准定时信号,走带速度的波动会在频谱上留下假峰。官方把这一点写进了局限清单,原论文也只报了时域指标。想算频域,得先按头文件字段筛记录,筛完剩下的样本量会掉一大截。

1.3 它能给到的与给不到的

你的需求 它给的 够不够
长时程 RR 间期序列 1543 条近 24 小时逐搏注释,累计约 1.5 亿个间期 够,这是它的本体
同一人用药前后对照 734 人各有 a、b 两条记录 够,公开数据里罕见
时域心率变异性(SDNN、SDANN 等) 注释完整,可直接差分 够,原论文就是这么用的
频域心率变异性(LF、HF、LF/HF) 约四成记录有校准定时信号 部分够,必须先筛
心搏形态分析 无波形 不够,完全不可能
室性早搏负荷统计 有 V 类标签,但发生率可能被低估 可做趋势,不宜做绝对值
房颤或起搏心律研究 相关受试者被排除在 Stein 的研究之外 不够,样本被系统性剔除
普通人群或健康基线 全部为心梗后、频发早搏者 不够
药物疗效的因果推断 无随机化后的完整对照臂,无安慰剂组 不够,只能做自身前后描述
训练深度学习模型 无波形,只有变长序列 可做序列模型,不可做卷积

1.4 你的处境与它能帮到的事

你的处境 它能帮你什么 下一步该做什么
你在做心率变异性的纵向研究,需要"干预前后同一人"的数据 提供 734 组配对记录,间隔与日期偏移都保留 先按受试者编号重建配对(§5.5),再确认两条记录的时长是否齐整
你手上有一个 RR 序列模型,想找一个跨度以年计的验证集 记录跨 1987 至 1991 年,季节跨度真实 用头文件日期做时间外推划分,别随机切
你在研究药物对自主神经的影响,苦于没有人体长时程数据 三种药物的分组本身就是天然的三臂 注意没有安慰剂臂,结论只能停在"用药前后有差异"
你要做频域算法,需要一个有已知伪影的真实数据集 六成记录带未校准时钟,是现成的压力测试材料 用头文件字段分层报告,把有/无定时信号当协变量
你在教 HRV 分析,需要一条 24 小时的真实序列 单条记录即可撑起一整节课 用 §2.3 的流程导出,注意年龄只有区间
你在核对某篇 2000 年前后 HRV 论文的复现性 原论文用的正是这批数据 先对齐人群定义(734 还是 769,见 §3.3)

1.5 一句话判断

它是一份被时间封存的对照实验:波形没了,只剩心跳的时刻,而恰恰是这个残缺的形态,让"同一个人用药前后"这件事在三十多年后仍然可以被重新计算。

1.6 不适合谁:四条边界

不适合任何需要波形的任务。 形态分类、ST 段分析、QRS 宽度测量、导联定位,一律无法开展。这不是数据质量问题,是数据不存在。

不适合把结论外推到普通人群。 入组要求是两年内急性心梗,且预处理 Holter 上室性早搏每小时不少于六次;九十天内入组者左室射血分数须不高于 55%,之后入组者须不高于 40%。这是一个心功能受损、心律失常负荷高的人群。

不适合做药物疗效的因果结论。 库内只有用药前后,没有安慰剂对照,也没有随机化后的完整随访。早搏抑制率八成以上是入组条件,不是结果变量。任何"某药改善 HRV"的表述都越过了数据能支撑的范围。

不适合当作 CAST 试验的代表样本。 CAST 主试验三千五百余人,这里 809 人,且是疗效筛选后的子集。用它估计 CAST 整体的死亡率或事件率会系统性偏低,因为被排除的正是用药无效者。

§2 数据构成与规格

2.1 一条记录只有一层:注释

WFDB 格式的记录通常由头文件、信号文件、注释文件三件套构成。这个库只有两件:.hea 与 .atr。头文件声明了零条信号通道,因此不存在 .dat,也没有任何采样点可读。

除记录本身,顶层还有三份清单文件:RECORDS 是全库记录名清单,一行一条,带药物目录前缀;ANNOTATORS 声明注释来源与角色;SHA256SUMS.txt 给出全库校验和。逐条比对文件是否存在,是判断一份心电数据能否做形态分析的最快方法——.atr 在而 .dat 不在,就意味着只能做时序分析,不存在第二条路。

头文件第一行的形式是 f004a 0 128 0 10:00:00 27/03/1989。第二个字段 0 表示信号通道数,第三个字段 128 是时间基准(每秒 128 个时间单位),第四个字段 0 是每通道采样点数,其后是起始时刻与日期。这里是注释时间的分辨率基准,不是波形采样率。

这一点值得单独强调,因为它决定了后续所有时间换算。注释里的时刻是整数,单位是 1/128 秒;把它转成秒要除以 128。个别记录的头文件写的是 125.44,那不是笔误,是重标定的结果。

2.2 字段与标签的完整字典

注释符号沿用 PhysioBank 的心搏类型定义。官方页面只描述了其中几类的语义,其余按平台通用码表理解。

符号 含义 官方是否明说 在本库中的典型用法
N 正常心搏 是(N-N 间期为分析对象) 绝大多数搏动
V 室性早搏 是 官方称几乎肯定是室早,但发生率可能低估
A 室上性早搏 是 同上,几乎肯定是室上早
Q 未分类 是 手工插入的搏动、起点测量错误者、超范围间期之后的搏动
F 融合波 否 按通用码表理解,官方未逐一说明
f 融合波(与正常搏动融合) 否 同上
L / R 左/右束支阻滞型心搏 否 同上
j / e 交界性逸搏等 否 同上
+ 节律改变标记 否 注释文件可能含,官方未展开

头文件的注释行是这份数据里信息密度最高的部分。每一行以 # 开头,字段固定。

头文件字段 示例 含义
<age-range> 60-64 年龄区间,5 岁一档
<sex> Male 性别
<medication> None / Flecainide 该条记录时的用药状态
<RR-low-limit(sec)> 0.656 分析所关注的 NN 间期下限
<RR-high-limit(sec)> 1.164 分析所关注的 NN 间期上限
Start time 10:00 记录开始时刻
First beat 10:02:37.585 首个心搏的相对时刻
Note recording with a timing signal 是否含校准定时信号
Note flutter-compensated 是否做过扑动补偿
Note reel-to-reel recording 记录载体为卷盘式磁带

RR-low-limit 与 RR-high-limit 容易被忽略,实际很关键。它们是当年分析者划定的"值得精确测量"的区间,落在区间外的间期没有被认真修正,紧随其后的搏动被标成 Q。所以这两个值不是数据范围,而是标注策略的边界。

2.3 一条记录的完整解剖

以 f/f004a.hea 为例,全部内容只有六行。

f004a 0 128 0 10:00:00 27/03/1989
#-- Start time=10:00
#-- First beat=10:02:37.585
#-- <age-range>: 60-64, <sex>: Male, <medication>: None
#-- <RR-low-limit(sec)>: 0.656,  <RR-high-limit(sec)>: 1.164
#-- Note: recording with a timing signal, flutter-compensated

逐行读下来能拿到这些信息:

行 可读出的事实 对下游的影响
第 1 行 记录名 f004a;无信号通道;时间基准 128;起始 10:00;日期 1989-03-27 时间换算基准,日期可用于季节性分析
第 2 行 记录从上午十点开始 无法确定是否跨夜,须配合时长判断
第 3 行 首个心搏在开始后 2 分 37 秒 说明前段空白,算小时负荷时要注意分母
第 4 行 年龄 60–64,男性,此刻未用药 基线记录,可与其 b 记录配对
第 5 行 有效 NN 区间 0.656–1.164 秒,约合 52–91 次/分 超出此范围的心率不被精确测量
第 6 行 有校准定时信号,已做扑动补偿 这条记录可用于频域分析

同一受试者的另一条记录 f004b 只差几处:日期变成 1989-05-02,用药字段变成 Flecainide,起始时刻变成 12:00,而 Note 变成了 reel-to-reel recording, not flutter-compensated。这一对记录正好展示了这个库最需要小心的地方:同一个人的两条记录,采集条件的可靠性可能完全不同。

f004b 0 128 0 12:00:00 02/05/1989
#-- Start time=12:00
#-- First beat=12:17:20.648
#-- <age-range>: 60-64, <sex>: Male, <medication>: Flecainide
#-- <RR-low-limit(sec)>: 0.617,  <RR-high-limit(sec)>: 1.14
#-- Note: reel-to-reel recording, not flutter-compensated

块内的注释行按全篇统一格式写作 #--,头文件原文是单个井号加空格。

两条记录的日期相差三十六天,同一个随机偏移保留了这个间隔,但绝对日期是虚构的。官方特意说明虚构日期足够接近真实日期,因此季节效应研究仍然可以开展。

2.4 三个药物组与配对结构

记录名首字母对应受试者随机分配到的药物。这是 CAST 的原始设计,不是事后分组。

首字母 药物 中文名 组内说明
e Encainide 恩卡尼 该臂于 1989 年 4 月被叫停
f Flecainide 氟卡尼 同上,同期叫停
m Moricizine 莫雷西嗪 延续至 CAST-II,后因死亡率趋势提前终止

末位字母表示该条记录所处的治疗阶段。a 是基线、用药前,此处的用药字段写 None,对应自身对照的前一半;b 是用药中,用药字段写着具体的药物名,对应后一半。把这两条放在一起,同一位受试者的"用药前"与"用药中"就成对了。

配对关系靠前四位(dnnn)识别。f004a 与 f004b 属于同一人,f004 是受试者标识。

结构 人数 记录数 说明
配对完整 734 1468 基线 + 用药中各一条
仅单条 75 75 只有一条可用记录,其余条件仍满足
合计 809 1,543 与 RECORDS 清单行数一致

这里有一处算术需要点明:734 乘 2 加 75 等于一千五百四十三,与官方给出的记录总数吻合,说明 734 是"有两条记录的人数"、75 是"只有一条的人数",两者相加得到 809。而原论文摘要写的是这个子研究共 769 人,与 734 相差 35,官方未解释差额构成。稳妥的表述是:存在两个口径,页面按记录结构给出 734 加 75,论文按入组条件给出 769,定义不同,差额原因未说明。

2.5 与同类资源的字段差异

把本库放进常见的心电数据里比较,最直观的差异是"有没有波形"这一列。

资源 波形 逐搏注释 长时程 配对设计 规模量级
本库 无 有 近 24 小时 有(734 组) 809 人
MIT-BIH 心律失常库 有 有 30 分钟 无 47 人
MIT-BIH 恶性室性心律失常库 有 有 30 分钟 无 35 人
长期房颤库 有 有 24 小时级 无 84 条
正常窦性心律库 有 有 30 分钟 无 54 条
十二导联长时程库 有 有 30 分钟 无 32 人

这张表说明它的位置:在"时长"和"配对"两列上它罕见地都占优,在"波形"一列上它是唯一一个空的。这就是它的全部筹码与全部代价。

另一层差异在元数据粒度。多数 PhysioNet 心电库给到年龄的确切值或十岁分组,本库给的是 5 岁一档的区间,比如 60 到 64 被并作一格,想当连续协变量用只能取组中值,误差随之而来。性别是二分类,与多数库一致。真正的差别在另外四项上:它记录用药状态,而且这个字段就是分组的依据;它记录采集起始时刻,精确到分;它记录采集日期,虽经随机偏移但间隔真实;它还记录设备的可靠性标记,包括是否含校准定时信号、是否做过扑动补偿、磁带是卷盘式还是盒式。相比之下,诊断信息反而粗糙,全库统一为心梗后,没有逐条的临床诊断。设备可靠性标记是这份数据最被低估的资产——它把"这条记录能不能做频域"从猜测变成了查表。

§3 核心层 A:它的真实身份

3.1 CAST 是一场被提前终止的试验

心律失常抑制试验由美国国立心肺血液研究所资助,设计目的是检验一个当时被广泛相信的假设:心梗存活者身上的无症状或轻微症状室性早搏如果被压下去,死于室性心律失常的人数会减少。入组门槛是两年内发生过急性心梗,且预处理长时程心电记录上室性早搏不少于每小时六次;心功能门槛随时间收紧,九十天内入组者左室射血分数不高于 55%,此后不高于 40%。

试验共入组 3,549 例,随机分配恩卡尼、氟卡尼、莫雷西嗪或安慰剂。用药后早搏显著被抑制者继续用该药或安慰剂。1989 年 4 月,数据与安全监察委员会建议停用恩卡尼与氟卡尼两个臂,原因是这两个药物组的死亡率过高,死因主要为心律失常、伴休克的急性心梗、以及慢性充血性心衰。

随后进行的 CAST-II 只保留莫雷西嗪与安慰剂,分两个双盲随机阶段:一个是评估心梗后起始用药风险的十四天暴露期,一个是评估长期生存效应的阶段。CAST-II 同样提前终止,长期使用莫雷西嗪与不用药或安慰剂相比呈现死亡率升高的趋势。试验作者的结论是:用莫雷西嗪抑制无症状或轻微症状的室早,不仅无效,而且有害。

3.2 子研究为什么要挑"用药有效"的人

Stein 的研究问题不是"药物有没有害",那已经由主试验回答了。她要问的是:生存与心率变异性的变化之间是什么关系,而这种变化在抗心律失常治疗下如何体现。这个问题要求记录里同时有"用药前"和"用药中"两段,而且两段都可用。

于是她设了三条筛选:有可用的用药前与用药中记录;随机分配到的药物在首次尝试就把室早率压低至少八成;并且继续使用该药。三条都满足的有 734 人,其中 69 人在研究期内死亡。

这个筛选把数据变成了一个非常特殊的样本:它是"药物确实起效"的那部分人。所以任何涉及"药物效果"的分析,用这个库都会得到偏乐观的图景,因为无效者被抽走了。

3.3 809 的三层构成

层次 人数 条件 在库中的形态
主试验入组 三千五百余例 心梗后 + 早搏≥6 次/小时 + 心功能门槛 不在库内
子研究合格 769(论文口径) 有可用双记录 + 首次用药即抑制八成 + 持续用药 论文分析对象
双记录齐备 734(页面口径) 同上,且两条记录都可用 a + b 两条
单记录 75 满足其余条件,仅一条可用 单条 a 或 b
库内合计 809 734 + 75 一千五百四十三条

三个数字之间的关系要这样读:809 是库的规模,734 是有配对的人数,769 是论文的分析样本。它们不是同一个量的三种说法,而是三种不同的纳入标准。写论文时如果引用了 769,就不能同时说"734 组配对",除非把口径讲清楚。

还有一处细节:官方提到有少数被收入本库的受试者,因为出现心房颤动或起搏心律,被排除在 Stein 的研究之外。也就是说,库比论文多了一点东西。这批人仍在库里,但不在论文的分析集里。

3.4 与 CAST 原始数据的关系

这条分界可以从四个方面看清。获取方式上,本库在 PhysioNet 公开、免注册下载,CAST 原始数据要向 NHLBI 申请并经过资格审核。内容上,本库只有逐搏注释与头文件,原始数据包含更完整的试验信息与随访字段。覆盖上,本库是 809 人,主试验是三千五百余人。许可上,本库是 ODC-BY 1.0,原始数据按申请协议走。用途也随之分开:本库适合方法学研究与算法评测,原始数据才支撑临床试验的二次分析。

有人在文献里看到"CAST 数据"就以为能下到全量,实际公开的只有这一个子研究,而且是被剥掉波形之后的版本。想做更广的分析,唯一的路径是走 NHLBI 的申请流程。

3.5 身份的三个易混点

第一,它不是 CRISPR 数据集。 crisdb 这个目录名里的 cris 来自 CAST RR Interval Sub-Study 的缩写组合,与基因编辑毫无关系。搜索引擎上以 crisdb 为关键词,很容易落到 CRISPR 相关的结果上,这是最常见的误判来源。

第二,它不是"CAST 数据库",而是 CAST 的一个子研究。 差别不只在规模,更在纳入标准:子研究只保留药物有效者。

第三,它不是波形库,也不是"RR 间期表格"。 它给的是逐搏注释,RR 间期需要自己差分得到。这个区别在工程上有实际后果:注释里保留了 Q 类搏动,差分时必须决定这些搏动怎么处理,处理方式不同,得到的序列长度与统计量都会变。

§4 核心层 B:质量与特色

4.1 标注是两遍扫描的产物

官方描述的方法很简短:全部记录由一位有经验的研究心律失常分析师按标准 Holter 分析流程扫描;心搏注释文件在第二遍编辑中修订,目的是识别测量错误的 RR 间期并剔除出后续分析。头文件里另记了少量附加信息。

这段话可以拆成三层含义。第一层是第一遍扫描:按标准 Holter 分析流程逐搏标注,得到初始注释。第二层是第二遍编辑:专门识别测量错误的 RR 间期,把它们剔除出后续分析,从而提高间期的可靠性。第三层是附加信息:头文件记下年龄、性别、用药、有效间期区间与设备标记,为后续分层提供依据。

需要强调的是,两遍都是人工。这不是算法初标加人工修正的模式,而是一位分析师从头到尾的工作。这带来两个后果:类型判断的一致性较好,因为出自同一双手、同一套标准;但工作量限制了规模,也意味着不存在"多标注者一致性"这类可以量化信度的指标。

4.2 时间轴:128 与 125.44

时间基准的差异值得单独讲,因为它是这个库里最技术性、也最容易踩的坑。

情形 头文件时间基准 原因 处理
常规 128 平台默认的注释时间分辨率 时刻除以 128 得秒
重标定 125.44 磁带记录速度 1.47 mm/s,扫描速度 1.50 mm/s,按比例折算 时刻除以 125.44 得秒

m010b 的头文件把这层意思写得很清楚:记录载体是卷盘式磁带,未做扑动补偿,时间已按记录速度与扫描速度之比重标定,即采样率从 128 Hz 调整为 125.44 Hz。

如果一律按 128 换算,这条记录的时间轴会偏大约百分之二。对 24 小时的记录来说,这是近半小时的累计误差;对 RR 间期这种以毫秒计的指标来说,这个偏差足以改变结论。反过来,把 1/128 秒误当成毫秒处理,误差是三个数量级,整个序列完全不可用。所以这里只有一条正确做法:读头文件的第三个字段,不要写死 128。

4.3 案例:f004 的两次记录

这是贯穿全文的例子,因为它把这份数据的优点与陷阱压缩在了同一个受试者身上。

f004a 是基线记录:1989 年 3 月 27 日上午十点开始,男性,年龄 60–64,未用药,有效 NN 区间 0.656 到 1.164 秒,有校准定时信号,做过扑动补偿。f004b 是用药中记录:1989 年 5 月 2 日中午十二点开始,同一位男性,服用氟卡尼,有效 NN 区间 0.617 到 1.14 秒,卷盘式磁带,无校准定时信号。

对比项 f004a(基线) f004b(用药中) 含义
日期 1989-03-27 1989-05-02 相隔三十六天,偏移已保留间隔
起始时刻 10:00 12:00 一天中的时段不同
用药 None Flecainide 配对的核心变量
有效 NN 下限 0.656 秒 0.617 秒 用药后上限心率提高
有效 NN 上限 1.164 秒 1.14 秒 下限心率也提高
定时信号 有 无 频域可用性不同
扑动补偿 已做 未做 同上

这一对记录能说明三件事。

第一,配对是真实的。同一个编号、同一个年龄区间、同一个性别,日期相隔一个多月,这与"用药前评估、开始用药、复查"的临床节奏吻合。

第二,两次采集的条件不对等。基线记录有定时信号且做了扑动补偿,用药中记录两者都没有。如果直接比较两条记录的频域指标,差异里混进了设备因素。这在配对设计里是个隐蔽的坑:配对控制了人,但没有控制设备。

第三,有效区间本身在变。用药后上下限都收紧了一点,说明当年分析者划定的关注区间随记录而调整。做跨记录比较时,用固定区间筛选和用各记录自己的区间筛选,会得到不同的序列。

§4.3 的案例在后面还会被引用两次:一次用来说明频域分析的分层策略,一次用来说明配对重建的实现。

4.4 Q 标签不是垃圾,是设计的一部分

Q 在这个库里出现的密度不低,容易被当成噪声直接丢掉。但官方对它的三条说明合起来,构成了一套明确的标注策略。手工插入的搏动一律标为 Q,也就是未分类;识别出起点测量不准的搏动,同样标为 Q;紧随异常长短 NN 间期的搏动,也标为 Q。至于漏检一个搏动后出现的约两倍长间期,官方只说明它属于噪声,没有讲这类位置的搏动是否改标 Q。

这三条的共同点是:Q 标记的是"这个搏动的时间或类型不可靠",而不是"这个搏动异常"。所以丢掉 Q 不等于丢掉异常搏动,恰恰相反,V 与 A 才是异常搏动,它们被保留了下来。

处理策略 序列长度 适用任务 风险
只保留 N 最短 时域 HRV 会丢掉部分真实异常节律
保留 N、V、A 中等 早搏负荷统计 间期序列含异位搏动,需另做校正
全部保留含 Q 最长 逐搏建模 Q 的时刻不可靠,污染序列
丢掉 Q 后重新计算间期 中等 通用做法 跨 Q 段的间期被拉长,需截断

官方还提醒了一点:V 与 A 标签几乎肯定对应真实的室性与室上性早搏,但它们的发生率可能被低估,因为超范围的长短间期没有被认真修正,紧随其后的搏动被标成 Q 而不是 V/A。做早搏负荷统计时,这个方向的偏差是单向的——只会少算,不会多算。

4.5 频域可行性的分级

把设备标记与时长结合,可以得到一张实用分级表。§4.3 的案例正好跨两级:基线记录有定时信号且做过扑动补偿,属可用频域的一类;用药中记录是卷盘式磁带、无定时信号,只能做时域。同一位受试者的两条记录分属不同等级,这正是分层必须按记录做、不能按人做的原因。

等级 记录特征 可用指标 约占全库
A 有校准定时信号 + 已做扑动补偿 时域 + 频域 少数,官方未给比例
B 有校准定时信号,未做扑动补偿 时域 + 频域(需自查扑动) 官方未给比例
C 卷盘式磁带,无定时信号 仅时域 官方称约六成属"无定时信号"一类
D 卷盘式 + 已重标定 时域,且须按 125.44 换算 官方未给比例

官方只给了"约六成磁带无校准定时信号"这一个比例,其余分档的具体数量没有公布。写分析计划时,应当把它当成分层变量,而不是当过滤器——先筛掉 C、D 会让样本量骤减,而且筛掉的人未必随机。

§5 核心层 C:取数与读取

5.1 目录结构

库的顶层目录很扁平,三个药物目录加一个历史目录。

路径 内容 数量
e/ 恩卡尼组的记录 官方未分组公布
f/ 氟卡尼组的记录 官方未分组公布
m/ 莫雷西嗪组的记录 官方未分组公布
old/ 早期版本遗留 官方未说明
RECORDS 全库记录名清单 1543 行
ANNOTATORS 注释角色声明 1 个文件
SHA256SUMS.txt 校验和 全库文件

RECORDS 的每一行是带目录前缀的相对路径,例如 e/e001a。这一点与某些同类库不同——那些库只写记录名,路径要自己拼。直接用这份清单循环读取,不需要额外判断。

5.2 取数

整库未压缩约 615 MB,压缩包约 617 MB,一次下完没有压力。三种方式都可。

#-- 1. 只取清单,先看结构
curl -sL https://physionet.org/files/crisdb/1.0.0/RECORDS -o RECORDS
wc -l RECORDS

#-- 2. 取单个受试者的两条记录做试读
for r in f/f004a f/f004b; do
  curl -sL "https://physionet.org/files/crisdb/1.0.0/${r}.hea" -o "$(basename $r).hea"
  curl -sL "https://physionet.org/files/crisdb/1.0.0/${r}.atr" -o "$(basename $r).atr"
done

#-- 3. 或者整库同步
aws s3 sync --no-sign-request s3://physionet-open/crisdb/1.0.0/ ./crisdb

第二条命令只取两个文件,适合在正式下载前确认联通性。第三条是官方给出的对象存储路径,比递归 wget 稳定,也支持断点续传。

5.3 读头文件

wfdb 读不到信号,但能读头文件。头文件的注释行会原样出现在 comments 字段里。

import wfdb

h = wfdb.rdheader('f004a', pn_dir='crisdb/f')
print(h.fs)          #-- 128.0:时间基准
print(h.sig_len)     #-- 0:没有采样点
print(h.n_sig)       #-- 0:没有信号通道
for line in h.comments:
    print(line)

输出的最后几行就是那四条注释。想把它结构化,需要自己按冒号切分,因为平台没有为这些字段定义正式的名称。年龄区间取 <age-range>: 之后到逗号的一段,注意它是区间不是数值;性别取 <sex>: 之后到逗号,值是大写开头;用药取 <medication>: 之后到行尾,None 表示基线;NN 下限与上限分别取两个 RR 区间字段之后的值,都是浮点秒;磁带类型看 reel-to-reel 是否出现,出现即为卷盘式。

定时信号与扑动补偿这两项要特别小心,因为它们是否定式表述。not flutter-compensated 与 flutter-compensated 都包含后者,直接用子串判断会把未补偿的记录全部判成"已补偿";“没有定时信号"也可能写成否定句而不是正句的缺失。最稳的写法是把整行拆成"键: 值”,再在值里检查否定词,而不是对整行做包含判断。

5.4 从注释到 RR 序列

RR 序列由相邻两次心搏的时刻差得到。关键在于先确定哪些符号参与。

import wfdb

def rr_series(rec, subdir, keep=('N',), fs=None):
    h = wfdb.rdheader(rec, pn_dir=f'crisdb/{subdir}')
    scale = fs or h.fs
    ann = wfdb.rdann(rec, 'atr', pn_dir=f'crisdb/{subdir}')
    t = [s / scale for s, sym in zip(ann.sample, ann.symbol) if sym in keep]
    return [b - a for a, b in zip(t, t[1:])]

rr = rr_series('f004a', 'f')
print(len(rr), rr[:5])

keep 的取值直接决定结果。只留 N 会得到最干净的序列,但跨越被丢弃搏动的间期会被保留成超长值,所以必须配一次区间截断。放行 N、V、A 三类,序列会包含异位搏动,做早搏负荷统计合适,但要把异位间期单独标记出来。全符号保留序列最长,同时把 Q 那些不可靠时刻一起收进来,不适合直接算 HRV。

那个"跨越式长间期"是这个库的已知问题。官方明确说序列里存在少量异常长间期,典型来源是 Holter 分析中的搏动检测错误——漏掉一个搏动,就会出现一个约两倍于正常值的间期。官方也承认罕见的窦性停搏可能贡献了少数几个,但由于原始心电图不可用,无法区分。

因此处理规则应当是:按头文件的上下限截断,而不是按统计量剔除。头文件给出的区间正是当年标注者的分析边界,用它与数据自身的标注策略保持一致;用三倍标准差之类的统计规则,会引入一套与原始设计无关的假设。

5.5 配对重建

配对靠记录名前四位识别,重建后可以按受试者做分组划分。§4.3 的案例恰好可以用来验证重建逻辑:f004 这个前缀下应当同时出现 a 与 b,且两条记录的年龄区间与性别一致,只有用药字段不同。

from collections import defaultdict

pairs = defaultdict(dict)
for line in open('RECORDS'):
    path = line.strip()
    if not path:
        continue
    sub, name = path.split('/')
    pairs[name[:4]][name[-1]] = (sub, name)

both = {k: v for k, v in pairs.items() if 'a' in v and 'b' in v}
print(len(pairs), len(both))

输出应当是 809 与 734。如果第一个数字对不上,多半是 RECORDS 末尾有空行或换行被吃掉,按非空行计数即可。四个数字可以互相校验:非空行数应为一千五百四十三,也就是记录总数;唯一前缀数应为 809,即受试者总数;同时含 a 与 b 的前缀数应为 734,即配对完整的人数;只含单一后缀的前缀数应为 75,即只有一条记录的人数。任何一个对不上,都说明解析逻辑有问题,而不是数据有问题。

划分训练与测试时按前缀分组,不按记录名分组。同一受试者的两条记录共享年龄、性别、体质、生活节律,随机按记录切分会让同一个人落到两侧。

5.6 五个最容易出错的地方

位置 错误写法 后果 正确做法
读取 用 rdrecord 读信号 直接报错或返回空 只用 rdheader 与 rdann
时间换算 写死除以 128 重标定记录偏 2% 读头文件第三个字段
设备字段 子串判断 flutter-compensated not 开头的也被判为已补偿 先拆键值再看否定词
序列清洗 用统计规则剔除长间期 与原始标注策略冲突 按头文件上下限截断
数据划分 按记录随机切分 同一受试者泄漏 按记录名前四位分组
人群描述 说成"心梗后人群" 忽略疗效筛选 写明"用药有效且持续用药"

§6 与库内条目的关系

6.1 关系图谱

在心电与生理信号这一类里,本库的位置由两个轴决定:有没有波形、有没有配对。它落在"无波形 + 有配对"这个角上,几乎没有邻居。

数据类型 波形 配对 与本库的关系
MIT-BIH 系列心律失常库 有 无 互补:它们给形态,本库给时长与配对
长期房颤库 有 无 互补:同为 24 小时级,一个有两导联波形,一个只有注释
正常窦性心律库 有 无 人群相反:那边是健康人,这边是心梗后
十二导联长时程库 有 无 维度不同:那边宽而短,本库窄而长
心率变异性专用库 多为有 少见 直接竞品,但配对设计罕见
可穿戴单导联库 有 少见 场景不同:那边是自由生活,这边是临床试验
本库 无 有 唯一角

如果你需要的正是"同一人、跨一次长期用药、两次 24 小时",替代品基本不存在;如果你需要的是别的任何组合,一般都有更合适的库。

6.2 检索路径

你要找的东西 检索词 会落到哪里
RR 间期分析工具链 ann2rr、wfdb-python、HRV howto §5.4 的读取方式
长时程注释型数据 annotation-only、RR interval database §2.5 的对比表
心梗后 HRV 研究 post-MI HRV、CAST §3 的身份说明与 §7.4
抗心律失常药与自主神经 encainide、flecainide、moricizine §2.4 的分组表
磁带伪影与频谱失真 wow and flutter、timing signal §4.2 与 §4.5
配对设计与自身对照 paired Holter、pre-post §5.5 的重建流程

6.3 与其他库的分工判据

任务 主粮仓该用什么 本库的位置 原因
心搏形态分类 带波形的标注库 不参与 无波形
节律分类 带波形与节律标签的库 不参与 无波形、无节律标签
时域 HRV 的纵向变化 本库 主力 配对 + 24 小时 + 逐搏
频域 HRV 的方法验证 带定时信号的少量记录 辅助 六成记录不可用
RR 序列异常检测 本库 主力之一 真实的长序列与真实的长间期噪声
药物对自主神经的影响 本库 唯一公开选项 三药分组 + 前后配对
人群基线建模 健康人群库 不适用 人群高度特化
波形生成或重建 带波形的库 不适用 没有可重建的目标

§7 质量评估与局限性

7.0 阅读本节前的一个前置校正

先纠正一个最容易发生的误判:把"没有波形"当成"数据质量差"。这两件事在评价体系里不在同一层。没有波形是数据形态的选择,它决定了适用任务的边界;质量差是数据在自身形态内不可靠。本库在自身形态内的可靠性相当高——两遍人工扫描、逐搏标注、设备条件逐条记录在案——但它能承载的任务范围很窄。

这个校正会改变五维评分的读法。如果按"通用心电数据集"打分,它在信号完整性与规模上都拿不到分;如果按"长时程 RR 间期与配对设计"打分,它在任务适配与结构完整性上接近满分。把这两套尺子混用,就会得出"这数据没用"或"这数据万能"两种相反的错判。

7.1 五维评分

按 DAIMS 的常用评价维度打分,每项 1 至 5 分,分数针对"作为长时程心率变异性研究数据"这个用途。

维度 分数 理由
数据规模 4 809 人、约 1.5 亿个间期,在 HRV 领域属大体量
标注质量 4 两遍人工、分析师单人完成,一致性无法量化
任务适配 5 配对加 24 小时,公开数据里罕见
文档完整 4 页面把人群、方法、五条局限写全,分组数量未公布
可获取性 5 免注册、ODC-BY、体量适中
形态完整性 1 无波形,是所有依赖形态的任务的硬约束

五项合计 22 分(不含形态完整性),加上形态完整性后是 23 分(满分 30)。这个分数结构说明它是一个专用工具:通用维度上缺一块形状,专用维度上接近满格。

7.2 标注质量的三个层次

第一层是类型判断。由一位有经验的研究分析师按标准 Holter 流程完成,第二遍编辑专门修订测量误差。类型标注的可靠性来源于人工与流程,但也因此无法给出标注者间一致性——只有一个人。

第二层是时刻精度。时刻来自注释采样点,单位 1/128 秒,理论上精度约 7.8 毫秒。但这是记录精度,不是生理精度:心搏起点本身的判定有误差,官方明确说测量起点错误的搏动被标成 Q。所以真实的时间误差大于名义精度。

第三层是覆盖完整性。官方承认 V 与 A 的发生率可能被低估,因为超范围间期未修正。这是单向偏差,做负荷统计时要写进局限。

这三个层次对应的可靠性并不相同,要分别交代。类型层的可靠性较高,威胁来自单人标注、没有一致性检验,引用时说明来源即可。时刻层是中等,威胁在于起点测量有误的搏动被标成 Q 而不是被修正,稳妥的做法是剔除 Q 之后按头文件区间截断。覆盖层偏低,威胁在于超范围间期未修正导致 V/A 被低估,所以只宜做趋势,不宜报绝对值。设备层不分高低,只分能否做频域,靠头文件字段分层即可。

7.3 已知的、可枚举的偏差

官方把局限写成了五条,逐条对应到下游影响如下。

偏差 官方表述要点 下游影响
无定时信号 约六成磁带为卷盘式或其它无校准定时信号的设备 频域分析出现走带速度波动造成的伪影
手工插入搏动 一律标 Q 序列中混入时刻不可靠点
起点测量错误 同样标 Q 同上
超范围间期未修正 关注区间外的 NN 未认真修正,其后搏动标 Q V/A 发生率被低估
原始信号缺失 波形不可用 无法验证、无法修正、无法研究形态
异常长间期 多为漏检导致,少数可能是窦性停搏 RR 序列含噪声,且无法区分来源

除官方列举之外,还有几条可以从数据结构直接读出、但不属于"官方局限"的事实,需要在方法学部分自行交代。

除官方列举之外,还有几条能从数据结构直接读出、却不属于"官方局限"的结构性偏差,需要在方法学部分自行交代。最要紧的是疗效筛选:只纳入首次用药即抑制八成以上者,这会让药物效应看起来比真实情况更好。其次是没有安慰剂臂:库内只有用药前后,无法把时间效应与药物效应分开。第三是人群特化:心梗后、频发早搏、心功能受损三者叠加,结论无法外推。第四是时段不匹配:基线多在上午,用药中可以在任意时刻,昼夜节律会混进前后差异。第五是设备不对等:同一人的两条记录可能来自不同设备,配对控制了人,没有控制设备。第六是年龄粗化到 5 岁一档,无法作连续协变量。第七是日期偏移,绝对日期虚构,季节分析可用、具体日期不可用。

第三条值得多讲一句。f004a 从上午十点开始,f004b 从中午十二点开始,这个差异本身就会影响 HRV——人的心率在一天中有明显的昼夜节律。配对设计消除了人与人的差异,但没有消除时段差异。做前后比较时,把起始时刻当作协变量,或者只在时段相近的子集里比较,是必要的稳健性检验。

7.4 外部验证矩阵

这个库在文献中的角色,可以从它的引用方式看出来。

验证角色 做法 讲得通的地方 风险
原研究的复现 按 2000 年论文的纳入标准重建分析集 数据就是那篇论文的来源 769 与 734 的口径差异会导致样本不一致
HRV 与预后的关联 用死亡受试者做结局分组 734 人中有 69 人死亡,有结局 死亡数少,统计功效有限
方法学基准 在真实长序列上测 RR 清洗算法 含真实的长间期噪声 无金标准,只能比相对优劣
频域方法验证 只在有定时信号的子集上做 条件清楚 子集小且非随机
机器学习外部测试 把 RR 序列模型放到本库外测 人群与设备都不同 只有序列,没有形态特征

第一行是最常见的用法,也最容易出问题:原论文的分析集是 769 人,页面描述的结构是 734 组配对加 75 条单记录,想复现论文必须按论文的条件重建。

7.5 它为何能持续:一种无法再生的对照

它没有更新、没有扩版,二十多年只发过一个版本,却仍然是心率变异性研究里被反复取用的数据。原因不在规模,而在于它占着一个无法再生的位置:三种已退市药物、同一批人的用药前后、各 24 小时的逐搏记录。

想复制这个设计,需要重新找到一批需要长期服用这类药的患者,而这三个药已经不在那个适应症上使用;需要重新做两次 24 小时 Holter,成本高且伦理上难以成立;还需要这批患者恰好对药物有反应。三个条件叠加,实际上等于不可能。所以它不是"暂时没有更好的替代品",而是"结构上不会再有第二个"。这个属性让它的价值随时间上升而不是下降。

§8 生态位与历史

8.1 历史沿革

时间 事件 与本库的关系
1980 年代末 CAST 入组与随访 原始磁带产生
1989 年 4 月 恩卡尼与氟卡尼臂被叫停 e、f 两组的用药期在此前后结束
1990 年代初 CAST-II 进行并提前终止 m 组记录的来源
2000 年 3 月 Stein 等发表 HRV 决定因素论文 子研究的分析成果
2004 年 7 月 2 日 数据库在 PhysioNet 发布 1.0.0 公开可获取的起点
至今 无新版本 结构与内容保持稳定

e 与 f 两组的"用药中"记录大多落在 1989 年上半年,m 组可以延伸到更晚,分组对应着试验进程。

8.2 与 CAST 及 CAST-II 的关系

三个层级的对应关系是:CAST 的四个臂里,恩卡尼与氟卡尼因死亡率过高被叫停,对应 e、f 两组;CAST-II 只留莫雷西嗪与安慰剂,因死亡率趋势提前终止,对应 m 组;子研究不新设任何臂,只回溯这三种药物的记录。

安慰剂臂不在库里。这是一个关键缺口:库内所有人都在某个时点用过药,没有一组"从未用药但同样随访"的对照。所以库内的"前后比较"只能回答"用药前后有没有变化",不能回答"变化是不是药物造成的"。

8.3 生态位:对照工具而非训练集

把它放在"主力粮仓"与"对照工具"这两个角色的对照里,区别就清楚了。主力粮仓负责大规模训练与预训练,前提是数据量大、标签细、有波形,失败模式是过拟合与标签噪声累积,代表资源是各类带波形的大规模心电库。对照工具负责自身前后比较与方法验证,前提是结构独特、条件清楚,失败模式是样本特化导致结论不可外推,代表资源就是本库这类专题型小库。

本库坐在后一列,而且坐得很稳。把它当训练集用,会立刻遇到"没有波形"这个硬墙;把它当对照工具用,它能提供别处拿不到的自身对照。

8.4 谁在用它,用来做什么

从公开文献的引用方式看,使用者集中在三类。第一类是心率变异性研究者,他们复现或扩展 2000 年论文的结论,关注人群定义、时域指标与结局关联。第二类是信号处理与算法组,他们在真实长序列上验证 RR 清洗与异常检测,关注长间期噪声与 Q 标签的处理方式。第三类是临床试验数据的二次利用者,他们把配对结构当作干预前后设计的模板,关注配对重建与设备分层。

第三类最少,但正是它把这个库与普通心电库区分开。它不只是"一批 RR 间期",它是一份带有干预结构的观察数据。

§9 使用指引

9.1 三种角色的路径

角色 第一天 第一周 注意事项
心率变异性研究者 读官方页面与头文件,跑通 §5.4 的序列提取 按受试者重建配对,做时域指标的自身前后比较 先定 Q 的处理规则,再算指标
算法工程师 取 §4.3 的案例两条记录,做可视化 在整库上测 RR 清洗算法,按设备字段分层报告 长间期的来源无法区分,别声称能区分
教学与临床工程 用单条记录演示 24 小时 RR 序列 用配对记录讲自身对照设计 强调没有安慰剂臂

9.2 一条最短的可用流程

#-- 1. 取清单与校验
curl -sL https://physionet.org/files/crisdb/1.0.0/RECORDS -o RECORDS
curl -sL https://physionet.org/files/crisdb/1.0.0/ANNOTATORS -o ANNOTATORS
cat ANNOTATORS

#-- 2. 取一个受试者的配对记录
for r in f/f004a f/f004b; do
  curl -sL "https://physionet.org/files/crisdb/1.0.0/${r}.hea" -o "$(basename $r).hea"
  curl -sL "https://physionet.org/files/crisdb/1.0.0/${r}.atr" -o "$(basename $r).atr"
done
ls -l f004a.* f004b.*
import wfdb
import numpy as np

def load_pair(sub, sid):
    out = {}
    for stage in ('a', 'b'):
        name = f'{sid}{stage}'
        h = wfdb.rdheader(name, pn_dir=f'crisdb/{sub}')
        ann = wfdb.rdann(name, 'atr', pn_dir=f'crisdb/{sub}')
        t = np.asarray(ann.sample, dtype=float) / h.fs
        rr = np.diff(t)
        lo = float([c for c in h.comments if 'RR-low-limit' in c][0].split(':')[1].split(',')[0])
        hi = float([c for c in h.comments if 'RR-high-limit' in c][0].split(':')[1])
        out[stage] = rr[(rr >= lo) & (rr <= hi)]
    return out

p = load_pair('f', 'f004')
for k, v in p.items():
    print(k, v.size, round(v.mean(), 4), round(v.std(), 4))

这段代码做了三件在别处容易漏的事:按头文件的时间基准换算、按头文件给出的区间截断、把两条记录成对取回。它没有做的事同样重要——没有剔除 Q 类搏动,因此间期序列里包含跨越 Q 的长值,截断会把它们一起切掉。

9.3 引用方式

引用对象 内容
数据集 Stein, P. (2004). CAST RR Interval Sub-Study Database (version 1.0.0). PhysioNet.
DOI 10.13026/C25P42
RRID SCR_007345
原始论文 Stein PK, et al. Clin Cardiol 23(3):187-94, 2000
平台 PhysioNet 平台综述论文,按官方页面引用按钮生成
附加数据 需向 NHLBI 申请,不在公开范围

写方法学部分时建议同时注明:使用的版本、是否按头文件字段筛掉了无定时信号的记录、Q 类搏动的处理规则、以及划分是否按受试者分组。这四项决定了别人能否复现你的数字。

§10 AI 使用声明

项目 声明
文本生成 本文由 AI 辅助撰写,编辑把关结构与事实
数字来源 规模、结构、边界三类数字来自 PhysioNet 官方页面与官方文件
文件核验 RECORDS、f004a.hea、f004b.hea、e001a.hea、m010b.hea 经直接访问确认
口径冲突 页面 734 与论文摘要 769 的差额,正文按"两个口径"处理,未作判断
论文信息 仅参考 Europe PMC 返回的摘要,未读全文
未核验内容 各药物组的具体记录数、按设备字段分层的比例、各标签的出现频次
图像 无配图;封面为生成式提示词,不含真实心电波形或患者信息
免责 本文不构成临床或用药建议;使用须遵守 ODC-BY 1.0 署名要求

常见误读(避坑清单)

说法 实际 证据
「crisdb 是 CRISPR 相关的库」 是 CAST RR Interval Sub-Study 的目录名 官方标题为 CAST RR Interval Sub-Study Database
「下载坏了,读不出信号」 头文件声明零通道、零采样点 f004a.hea 第一行第二个字段为 0
「它有一万五千条记录」 一千五百余条,受试者八百余人 RECORDS 行数与官方摘要
「它是 CAST 全队列」 主试验三千五百余人,库内仅 809 人 官方页面 Background 段
「它能算 LF/HF」 约六成记录无校准定时信号 官方 Usage Notes 第一条
「Q 是被判为异常的心搏」 Q 表示时间或类型不可靠,异常搏动用 V/A 表示 官方对 Q 的三条说明
「室早负荷可以直接算绝对值」 官方承认 V/A 发生率可能被低估 官方 Usage Notes 第三条
「同一个人两条记录可以当两个样本」 同一受试者的 a 与 b 高度相关 记录名共前缀,头文件年龄性别一致
「日期是真的,可以做具体日期分析」 日期经随机偏移,仅间隔真实 官方 Methods 段
「年龄是确切值」 5 岁一档的区间 头文件 <age-range> 字段
「它是健康人基线库」 全部为心梗后、频发早搏者 官方入组条件

FAQ

Q1:crisdb 是不是 CRISPR 基因编辑数据库?
不是。它是 CAST RR Interval Sub-Study Database 的目录名,CAST 指心律失常抑制试验。库内另有一个 CRISPR 图谱数据集,两者毫无关系。用搜索引警找 crisdb 时最容易撞上 CRISPR 的结果,这是本库最常见的误认来源。

Q2:为什么下载下来只有注释,没有波形?
官方明确写了原始心电信号不可用。这批数据来自 1980 年代末的 Holter 磁带,子研究只保留了逐搏注释与头文件。后果是:无法验证记录的间期、无法修正搏动标签、也无法研究心搏间期以外的任何心电特征。

Q3:能不能用它算频域心率变异性?
要按记录筛。约六成磁带录制时没有校准定时信号,这类记录存在走带速度波动造成的频域伪影。每份头文件都标了是否含定时信号,做频域前必须先按这个字段筛选。原论文本身也只报了时域指标,理由是许多磁带缺少频域分析所需的校准定时信号。

Q4:同一个人有两条记录,能当两个独立样本吗?
不能。a 与 b 是同一位受试者用药前后的两次记录,年龄、性别、体质、生活节律全部共享。划分训练与测试时必须按受试者编号分组,否则同一个人会同时出现在两侧,指标会虚高。

Q5:它和 CAST 原始试验数据是一回事吗?
不是。主试验入组三千五百余人,本库只覆盖 809 人,且是满足用药有效、持续用药等条件的子集。更完整的 CAST 与 CAST-II 数据需要向 NHLBI 申请,不在公开范围内。

Q6:为什么有时看到 734 人,有时看到 769 人?
734 是 PhysioNet 页面按记录结构给出的人数,指同时具备基线与用药中两条记录的人;769 是 2000 年论文摘要里的分析样本量。两者纳入标准不同,差额的构成官方未说明。写论文时选一个口径并讲清楚,不要混用。

Q7:记录名里的 e、f、m 和 a、b 是什么?
首字母是药物:e 对应恩卡尼,f 对应氟卡尼,m 对应莫雷西嗪。末位是阶段:a 为用药前基线,b 为用药中。中间三位是受试者编号。所以 f004a 与 f004b 属于同一位服用氟卡尼的受试者。

Q8:为什么有的记录时间基准是 125.44 而不是 128?
因为磁带记录速度与扫描速度不一致。官方在头文件里说明了:按 1.47 mm/s 记录、1.50 mm/s 扫描的比例重标定,采样率从 128 调整为 125.44。遇到这种记录,时刻要除以 125.44,否则时间轴会偏大约百分之二。

Q9:Q 类搏动能不能直接丢掉?
可以丢,但要理解丢的是什么。Q 标记的是"这个搏动的时刻或类型不可靠",包括手工插入的、起点测量错误的、以及紧随超范围间期的搏动。丢掉 Q 之后,跨越被丢搏动的间期会变成超长值,仍需要按头文件区间截断。

Q10:序列里那些特别长的间期是什么?
官方说主要是 Holter 分析中的搏动检测错误,比如漏掉一个搏动就会产生一个约两倍长的间期。少数也可能是真正的窦性停搏,但因为原始心电图不可用,无法区分。处理时按头文件给出的上下限截断,不要用统计规则。

Q11:它能不能用来研究药物疗效?
只能做"用药前后有没有变化"的描述,不能做因果结论。库内没有安慰剂臂,所有人都在某个时点用过药;而且纳入条件是"药物确实有效",无效者已被筛掉。任何"某药改善 HRV"的表述都超出了数据能支撑的范围。

Q12:许可允许商用吗?
ODC-BY 1.0 允许,包括商业用途,条件是署名。引用时写清数据集名称、版本、DOI 与来源。具体条款以许可全文为准。

术语表

术语 解释
CAST 心律失常抑制试验,NHLBI 资助的心梗后抗心律失常药试验
CAST-II CAST 的后续试验,只保留莫雷西嗪与安慰剂两组
子研究 从主试验中取子集做二次分析的研究,本库即其产物
RR 间期 相邻两次心室除极之间的时间间隔
NN 间期 相邻两次正常心搏之间的间隔,已排除异位与不可靠搏动
心率变异性 逐搏间期随时间的波动程度,反映自主神经调节
时域指标 直接从间期序列算的统计量,如 SDNN、SDANN
频域指标 对间期序列做频谱分析得到的功率,如 LF、HF
室性早搏 心室提前除极,形态宽大,简称室早
室上性早搏 起源于心室以上的提前搏动,简称室上早
扑动补偿 对记录设备走带或扫描速度偏差所做的校正
校准定时信号 录制时同步写入的时间基准信号,频域分析的前提
卷盘式磁带 reel-to-reel,早期 Holter 常用载体,速度稳定性较差
走带抖动 wow and flutter,磁带速度波动造成的频率失真
注释文件 .atr,存放逐搏时刻与类型符号的二进制文件
头文件 .hea,纯文本,声明时间基准与记录元数据
WFDB PhysioNet 使用的生理信号数据格式族
时间基准 头文件声明的每秒时间单位数,本库多为 128
分析集 论文实际纳入统计的样本,本库论文口径为 769 人
自身对照 同一个体在干预前后的比较,本库的配对结构即此
疗效筛选 只纳入对治疗有反应者,会引入选择偏倚
左室射血分数 心脏每次收缩射出的血比例,CAST 的心功能门槛
去标识 移除或扰动可识别个体的信息,本库扰动的是日期
ODC-BY 开放数据共享署名许可,允许商用需署名
PhysioNet 由 MIT 等机构维护的生物医学信号数据平台

附录 A:核心数字核对表

项 值 来源 来源层级
受试者数 809 官方页面 Background 段 官方页面
记录数 1543 官方页面;RECORDS 行数 官方页面 + 官方文件
配对人数 734 官方页面 Background 段 官方页面
单记录人数 75 官方页面 Background 段 官方页面
论文分析样本 769 Europe PMC 摘要 论文摘要
配对组内死亡数 69 官方页面 Background 段 官方页面
主试验入组数 3,549 官方页面 Abstract 段 官方页面
每记录时长 约 24 小时 官方页面首段 官方页面
累计 RR 间期 约 1.5 亿 官方页面首段与 Usage Notes 官方页面
时间基准 128 Hz f004a.hea 等 官方文件
重标定基准 125.44 Hz m010b.hea 官方文件
药物组数 3 官方页面 Data Description 官方页面
无定时信号比例 约六成 官方页面 Usage Notes 官方页面
未压缩体积 615.4 MB 官方页面 Files 区 官方页面
压缩包体积 616.6 MB 官方页面 Files 区 官方页面
许可 ODC-BY 1.0 官方页面 License 区 官方页面
首版日期 2004-07-02 官方页面 官方页面
DOI 10.13026/C25P42 官方页面 Discovery 区 官方页面

附录 B:数字的来源分层

第一层:官方页面与官方文件。 受试者数、记录数、配对数、单记录数、死亡数、主试验规模、时长、累计间期、药物组、无定时信号比例、体积、许可、日期、DOI,以及时间基准与重标定值,均来自项目主页与 RECORDS、若干头文件的直接访问。

第二层:论文摘要。 769 这个分析样本量、以及"只报时域指标因为许多磁带缺校准定时信号"这一方法学说明,来自 Europe PMC 返回的摘要。摘要只能支撑"论文这样写",不能支撑"全库如此"。

第三层:未核实。 三个药物组各自有多少条记录、按设备字段分层后的比例、各标签的出现频次、异常长间期的数量分布。这些需要下载全库逐条统计,超出本篇范围,正文中凡涉及处只做定性表述。

附录 C:完整参考文献

编号 文献 链接 用途
1 CAST RR Interval Sub-Study Database v1.0.0 https://physionet.org/content/crisdb/1.0.0/ 全部规模、结构、边界数据的来源
2 该库的 PhysioNet 文件目录 https://physionet.org/files/crisdb/1.0.0/ RECORDS、头文件、ANNOTATORS
3 Stein PK, et al. Clin Cardiol 2000;23(3):187-94 https://pubmed.ncbi.nlm.nih.gov/10761807/ 子研究设计与分析样本
4 Echt DS, et al. N Engl J Med 1991;324:781-8 https://doi.org/10.1056/NEJM199103213241201 CAST 主试验结论
5 CAST-II Investigators. N Engl J Med 1992;327:227-33 https://doi.org/10.1056/NEJM199207233270403 莫雷西嗪臂结论
6 Epstein AE, et al. J Am Coll Cardiol 1991;18:14-19 https://doi.org/10.1016/s0735-1097(10)80210-4 CAST 全队列事件
7 PhysioNet 平台综述(2026,Nature Health) https://doi.org/10.1038/s44360-026-00096-z 托管模式与引用规范
8 PhysioBank 注释定义 https://physionet.org/physiobank/annotations.shtml 心搏类型码含义
9 RR 间期与 HRV 操作指南 https://physionet.org/content/annotations/ ann2rr 与序列导出

附录 D:任务代码

任务一:按受试者分组的配对表构建

from collections import defaultdict
import json

pairs = defaultdict(dict)
for line in open('RECORDS'):
    path = line.strip()
    if not path:
        continue
    sub, name = path.split('/')
    pairs[name[:4]][name[-1]] = f'{sub}/{name}'

rows = []
for sid, d in sorted(pairs.items()):
    rows.append({'subject': sid, 'drug': sid[0],
                 'baseline': d.get('a', ''), 'therapy': d.get('b', '')})

print(len(rows))
print(sum(1 for r in rows if r['baseline'] and r['therapy']))
json.dump(rows, open('subjects.json', 'w'), ensure_ascii=False, indent=1)

任务二:头文件字段的结构化解析

import re
import wfdb

def parse_hea(rec, subdir):
    h = wfdb.rdheader(rec, pn_dir=f'crisdb/{subdir}')
    txt = ' '.join(h.comments)
    def grab(key, stop=r'[,;]'):
        m = re.search(key + r'\s*[:=]\s*([^,;]+)', txt)
        return m.group(1).strip() if m else ''
    note = grab('Note', stop=r'$')
    return {
        'fs': h.fs,
        'age_range': grab(r'<age-range>'),
        'sex': grab(r'<sex>'),
        'medication': grab(r'<medication>'),
        'rr_lo': float(grab(r'<RR-low-limit\(sec\)>')),
        'rr_hi': float(grab(r'<RR-high-limit\(sec\)>')),
        'timing_signal': ('timing signal' in note) and ('no timing' not in note),
        'flutter_comp': ('flutter-compensated' in note) and ('not flutter-compensated' not in note),
        'reel_to_reel': 'reel-to-reel' in note,
    }

print(parse_hea('f004a', 'f'))
print(parse_hea('f004b', 'f'))

第二个函数的关键在最后三行:否定式表述必须显式排除,否则 not flutter-compensated 会被判成已补偿。这个坑在 f004a 与 f004b 这一对上正好能验证——前者应为已补偿,后者为未补偿。

任务三:设备条件分层后的描述统计

import numpy as np

def summarize(rec, subdir):
    h = wfdb.rdheader(rec, pn_dir=f'crisdb/{subdir}')
    ann = wfdb.rdann(rec, 'atr', pn_dir=f'crisdb/{subdir}')
    t = np.asarray(ann.sample, dtype=float) / h.fs
    rr = np.diff(t)
    return {'n': rr.size, 'median_s': float(np.median(rr)),
            'fs': h.fs, 'span_h': float(t[-1] - t[0]) / 3600.0}

for r, s in (('f004a', 'f'), ('f004b', 'f'), ('m010b', 'm')):
    print(r, summarize(r, s))

这段代码返回的是记录级摘要,不是人群统计。它的用途是快速确认时间基准、时长量级与是否需要对某条记录单独处理,不用于推断分布。

附录 E:如果只记五件事

序号 记住什么 为什么
1 809 人、1543 条、每条约 24 小时、只有注释没有波形 这四个事实定义了一切用法与限制
2 734 人有用药前后配对,这是它最稀缺的部分 随机对照无法重做,配对结构不可再生
3 约六成记录无校准定时信号 频域分析前必须按头文件字段筛选
4 时间是 128 的分数秒,个别记录是 125.44 写死 128 会让时间轴偏约百分之二
5 人群是"心梗后 + 药物治疗有效"者 结论不能外推到普通人群,也不能当归因于药物

编辑说明

本文的核验时间为 2026 年 10 月 28 日。核对方式为直接访问 PhysioNet 项目页与文件目录,逐一确认 RECORDS、f004a.hea、f004b.hea、e001a.hea、m010b.hea 的可访问性与内容;论文侧只检索了 Europe PMC 的摘要,未读全文。

有一处口径冲突需要在此留痕:PhysioNet 页面按记录结构给出"734 人配对 + 75 人单条 = 809 人",而 2000 年论文摘要写的是子研究 769 人。两者相差 35 人,官方未说明差额构成。本文的处理方式是并列陈述、不作判断,并在 §3.3、§7.4 与 FAQ 第 6 问三处提示使用者注意,避免复现时误用。

本篇对 crisdb 这个名称做了一次专门辨析(§3.5、FAQ 第 1 问)。目录名与 CRISPR 的拼写相近,是这个词条最容易被误认的地方,检索与引用时需加以区分。未覆盖的项包括三个药物组各自的确切记录数、按设备字段分层的比例、各标签的出现频次与异常长间期的分布,这些需要下载全库统计。


相关数据集导航

以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:

  • wctecgdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • ahadb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • chfdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • cudb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • ltdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • ltstdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • iafdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • nsr2db — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • nsrdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • stdb — 共享标签:生理信号 / 心电信号 / 心血管疾病

导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

返回 AI-Ready 数据集