信息速览
AMRnet 是一个把抗菌素耐药(Antimicrobial Resistance,AMR)的基因组证据摊开给人看的平台。它本身不测序,也不做实验,而是把 Pathogenwatch 和 EnteroBase 里已经算好的耐药基因与谱系结果,按菌种、国家、年份重新聚合成一张可以点击的世界地图。官方定位写得很直白:让没有生物信息学背景的人也能读懂基因组里编码的耐药信息,让政策制定者看得见。
它最值得写的地方,是它把两样东西放在同一个界面上:一个是「这一国这一年的分离株里,多大比例带某个耐药基因」,另一个是「这一国这一年到底测了多少株」。前者是分子上的比例,后者是分母。公共卫生领域长期只有前者(药敏监测网报的耐药率),很少同时给出后者;而基因组分母的含义与药敏监测的分母并不一样,它衡量的是「被送去测序的菌株」,不是「全部病例」。
本文的主轴只有一句:同一个耐药基因,不同国家报出来的数字相差一个数量级,多半不是生物学差异,而是测序覆盖率差异、抽样目的差异和时间滞后叠加出来的。下文所有章节都围绕这句话展开,中间会用一个具体的国家分组反复演示。一屏速览见下表。
| 维度 | 内容 |
|---|---|
| 中文名 | 抗菌素耐药基因组监测网络(AMRnet) |
| 英文名 | AMRnet |
| 定位 | 公共基因组数据的耐药可视化聚合层,不产数据 |
| 维护机构 | 伦敦卫生与热带医学院(LSHTM)项目组 |
| 上线形态 | 网页仪表盘(amrnet.org)+ 公开 S3 快照 + REST API |
| 病原面板 | 八个,覆盖伤寒、非伤寒沙门菌、侵袭性非伤寒沙门菌、肺炎克雷伯菌、淋球菌、大肠埃希菌、致泻性大肠埃希菌、志贺菌与 EIEC |
| 上游数据源 | Pathogenwatch(伤寒、克雷伯、淋球菌)、EnteroBase(其余) |
| 耐药识别工具 | Kleborate(克雷伯)、AMRFinderPlus(大肠、志贺、非伤寒沙门)、淋球菌用人工维护的决定簇字典 |
| 行的含义 | 一行 = 一株分离株在某版快照中的整理结果 |
| 主键 | Amrnet_id(面板内唯一;跨快照比对建议改用 ACCESSION) |
| 展示门槛 | 过滤后样本数 N≥20 才在地图出数,否则置灰 |
| 交付格式 | TSV(面板按钮)/CSV.gz(S3 快照)/JSON(API) |
| 软件许可 | GPLv3 |
| 官方更新 | 各面板文档标注「最后更新 2025 年 8 月 5 日」 |
| 论文 | Nucleic Acids Research 2026 年数据库专刊,DOI 10.1093/nar/gkaf1101 |
| 访问门槛 | 网页与 S3 免费直取;API 需免费注册取密钥 |
§1 它要解决的具体麻烦
1.1 公共测序库里躺着的耐药信息,进不了公共卫生的视野
过去十年,全基因组测序从研究工具变成了病原体鉴定的常规手段。每一次测序都会顺带产出耐药基因的信息:有没有 blaCTX-M-15,gyrA 第 83 位是不是丝氨酸换成了苯丙氨酸,有没有 qnrS。这些信息写在 FASTQ 和注释表里,对一个国家的卫生部门来说,它们的可见度接近于零。
官方文档对这个困境的描述很克制:「我们不生成序列数据,但我们希望通过让公共存放的数据更容易被获取和更有用,来鼓励更多的测序和数据共享。」论文摘要把话说得更重:公共档案里有大量细菌序列数据,但其中编码的 AMR 信息对没有生信能力的人并不易得,对政策制定者基本是不可见的。
AMRnet 解决的正是这个「可见度」问题。它把散落在各个项目里的分离株,压成国家 × 年份 × 耐药变量的一个矩阵,再把这个矩阵画成地图和趋势线。使用者不需要知道什么是组装、什么是决定簇,也能看到一个国家最近十年头孢曲松耐药的比例有没有往上涨。
1.2 三条常见的错误期待
第一条期待是「它是一个全球耐药率数据库」。不是。它是一个基因组来源的耐药率数据库,分子来自基因型预测,分母来自测序量。它与 WHO GLASS 这类基于实验室药敏的监测网,分子与分母都不是一回事。
第二条期待是「它的数字可以直接引用为某国耐药率」。部分可以,但引用时必须带上「测序菌株中」这个限定语。把「测了序的菌里 62% 耐药」写成「该国 62% 耐药」,是本文反复提醒的那类错误。
第三条期待是「它覆盖所有病原和所有国家」。它只覆盖八个病原面板,且每个面板的地理覆盖极不均匀,多数国家的样本数达不到地图出数的门槛。官方文档对这一点没有粉饰:剩下的国家在地图上是灰的。
1.3 它能给到的与给不到的
| 你的需求 | 它给的 | 够不够 |
|---|---|---|
| 某国某年伤寒 MDR 比例 | 地图与趋势图上的合并估计,附分子分母 | 够,但须注明是测序菌株中的比例 |
| 某国测了多少株 | 地图悬停与下载表里的样本计数 | 够,这正是它比同类强的地方 |
| 全球耐药负担总量 | 只给比例,不给全人口外推 | 不够,须另接发病率或就诊数据 |
| 耐药基因与谱系的对应 | 每个面板的基因型、ST、cgST 字段 | 够 |
| 某基因的逐年上升曲线 | AMR 趋势图按耐药变量与年份分组 | 够 |
| 原始测序读段 | 不提供,只到组装与决定簇层 | 不够,须回溯上游库 |
| 临床药敏结果对照 | 不提供,平台无表型列 | 不够,须接 GLASS 或医院数据 |
| 按医院、按年龄、按性别的分层 | 仅克雷伯面板有少量宿主字段 | 基本不够 |
| 因果解释(为什么耐药率上升) | 只做描述,不做归因 | 不够 |
这张表最重要的两行是第二行和第三行。同类可视化工具几乎都给第一行,少数给第二行,几乎没有同时给两行的。AMRnet 的价值就在第二行:它把分母摆出来了,而且摆在数字旁边,不是藏在附录里。
1.4 你的处境与它能帮到的事
| 你的处境 | 它能帮你什么 | 下一步该做什么 |
|---|---|---|
| 你在为国家耐药行动计划写基线章节,需要一个跨国的耐药图景 | 提供八种病原的国家级年度估计与趋势线,可直接导出 TSV | 导出后逐一核对分母,分母过小的国家只能写进「数据缺乏」小节 |
| 你在做某国产碳青霉烯酶肠杆菌的分子流行病学 | 克雷伯面板给 ST、cgST、耐药基因与亚谱系 | 必须先读 §4 的案例,确认该国样本是否以产酶株为主 |
| 你要训练一个从基因组预测耐药表型的模型 | 上游平台是标准的,本平台不提供读段与组装 | 不要用它训练,回到 Pathogenwatch 或 SRA/ENA 取原始数据 |
| 你在评估一个国家的测序能力建设成效 | 可以看该国年测序量随时间的形状 | 这恰好是它最擅长、也最容易被忽略的用途 |
| 你是临床医生,想知道某个病人该用什么药 | 平台只到国家年度层面,无个体信息 | 不应在临床决策中使用本平台 |
| 你在做新闻或政策简报,需要一句话结论 | 地图非常直观,适合做图 | 引述时务必同时给出分母,否则结论会被夸大 |
| 你在教一门基因组流行病学课程 | 面板本身就是一个很好的「同一数据两种读法」教具 | 用 §4 的案例做课堂练习最合适 |
| 你在找一份可以直接进数据仓库的静态表 | 每周 S3 快照,CSV.gz,无需密钥 | 建立每周拉取任务即可,注意跨版本主键会变 |
1.5 一句话判断
这是一个把「分子耐药预测」和「测序覆盖率」并排放的可视化层;它的历史价值不在画了多少张图,而在它第一次让使用者看见了自己的分母。
1.6 不适合谁:四条边界
第一条,不适合拿来做临床用药决策的人。平台的一切数字都是国家年度层面的,没有个体、没有医院、没有药敏结果,且时间上滞后一年以上。任何以它为依据的处方都是错的。
第二条,不适合要训练预测模型的人。它给的是已经算好的决定簇列,没有读段、没有组装质量、没有变异坐标,拿它训练模型等于拿别人的结论训练模型,学不到序列层面的规律。
第三条,不适合把国家间差异当作生物学差异的人。如果你的研究问题是「哪国产的菌更耐药」,这个平台无法回答,因为它的国家间差异里混着覆盖率、抽样目的、年份分布的差异,而这些混杂因素在平台内不可分离。
第四条,不适合需要近一年数据的人。文档标注的最后更新日期是 2025 年 8 月 5 日,快照对象的最后修改时间也是同一周,此后一年的真实变化在平台上不可见。
§2 数据构成与规格
2.1 八个面板:一张表看清各自的上游与整理状态
AMRnet 不是一个单一数据集,而是八个结构相似、来源不同的宽表。理解这一点是正确使用的前提:每个面板的字段、门槛、整理程度都不一样,跨面板的比较比跨国比较还要危险。
| 面板(面板短名) | 上游 | 耐药识别工具 | 采样目的整理 | 主键前缀 | 规模口径 |
|---|---|---|---|---|---|
| Salmonella Typhi(styphi) | Pathogenwatch | Pathogenwatch 决定簇字典 | 已整理,仅保留非靶向采样框 | amrnet-st | 万级 |
| Salmonella 非伤寒(senterica) | EnteroBase | AMRFinderPlus | 未整理 | amrnet-sent | 十万级 |
| Salmonella 侵袭性非伤寒(sentericaints) | EnteroBase | AMRFinderPlus | 未整理 | amrnet-sentint | 万级 |
| Klebsiella pneumoniae(kpneumo) | Pathogenwatch | Kleborate v3 | 未整理 | amrnet-kp | 三万级 |
| Neisseria gonorrhoeae(ngono) | Pathogenwatch | 人工维护决定簇字典 | 已整理,含 EuroGASP 与国家监测研究 | amrnet-ng | 两万级 |
| Escherichia coli(ecoli) | EnteroBase | AMRFinderPlus | 未整理 | amrnet-ec | 四万级 |
| E. coli 致泻型(decoli) | EnteroBase | AMRFinderPlus | 未整理 | amrnet-dec | 千级 |
| Shigella + EIEC(shige) | EnteroBase | AMRFinderPlus | 未整理 | amrnet-sh | 四万级 |
这张表里最该被记住的是「采样目的整理」这一列。八个面板里只有伤寒与淋球菌两个完成了这一步,其余六个面板的官方页面都挂着警示:数据尚未针对采样目的做整理,因此仍反映全球测序偏向——测序资源大量投给了产 ESBL、产碳青霉烯酶或高毒力的菌株。这句话的意思是,那六个面板里凡是出现耐药菌的国家,其耐药比例多半被系统性抬高。
规模一列的数值取自公开快照的记录计数(已扣除表头),属于「规模」类数字,用于判断够不够用;各面板的具体行数在附录 A 给一次,正文不再重复。之所以不在此处逐个列出,是因为快照每周重发,精确数字在正文里写死反而会迅速过期,而行数本身也不是选择这个平台的理由。
2.2 字段字典:一条记录里有什么
以伤寒面板为例,一条记录有 101 个字段。这 101 个字段可以分成五组,分组比逐个罗列更有用,因为使用者在选列时是按组来想的。
| 组别 | 代表字段 | 含义 | 取值与陷阱 |
|---|---|---|---|
| 版本层 | Amrnet_id、Amrnet_version、Amrnetdb_version、Amrnetdb_date | 记录身份与快照版本 | Amrnet_id 形如 amrnet-st_1,面板内唯一;Amrnetdb_date 是整库日期,不是采样日期 |
| 来源层 | Pathogenwatch_id、ACCESSION、PROJECT ACCESSION、BIOSAMPLE、PMID、LAB、CONTACT | 上游标识与文献钩子 | ACCESSION 是与外部库连接的唯一稳妥键 |
| 流行病学层 | DATE、COUNTRY_ONLY、REGION_IN_COUNTRY、TRAVEL、COUNTRY_ORIGIN、TRAVEL_LOCATION、COUNTRY ISOLATED、TRAVEL ASSOCIATED | 时间地点与旅行相关标记 | 旅行相关病例归到旅行国而非分离国,这是官方明确的规则 |
| 采样层 | SOURCE、SYMPTOM STATUS、PURPOSE OF SAMPLING、AGE、TRAVEL COUNTRY | 标本来源、症状、采样框架 | PURPOSE OF SAMPLING 取值为 Non Targeted 与 Targeted 两大类,是分母含义的钥匙 |
| 结果层 | gyrA_、parC_、blaCTX-M-、sul1、dfrA、tetA(*)、MDR、XDR、amr_category、num_amr_genes、GENOTYPE、GENOTYPE_SIMPLE、h58_genotypes、MLST ST | 耐药决定簇与谱系 | 决定簇列是 0/1 二值;类别列是聚合后的标签 |
五个组里,采样层是最容易被跳过、却决定一切的一组。同一株菌,如果它来自「Non Targeted [Surveillance Study]」,它对国家耐药率的贡献是正当的;如果来自「Targeted [AMR investigation]」,它本身就因为是耐药菌才被选中测序,放进合并估计里就会把比例抬高。伤寒面板已经在整理阶段把后者的大部分剔除了,其他面板没有。
不同面板的字段数差异很大:伤寒 101 列,淋球菌 99 列左右,克雷伯 164 列,大肠埃希菌 86 列,志贺 88 列。克雷伯之所以最宽,是因为它把每种药物的预测结果都单列成一列(tetracycline、ampicillin/sulbactam、amikacin、cefepime、tobramycin、piperacillin-tazobactam 等),而伤寒把耐药集中在少数几个决定簇与类别列上。
| 面板 | 字段数 | 耐药结果呈现方式 | 特有字段 |
|---|---|---|---|
| 伤寒 | 101 | 决定簇二值列 + MDR/XDR 类别 | dcs_category、h58_genotypes、GENOTYPE_SIMPLE |
| 非伤寒沙门 | 约 90 | AMRFinderPlus 类别二值 | Source Niche、Source Type、Sourcify |
| 侵袭性非伤寒沙门 | 约 90 | 同上 | 侵袭性判定相关列 |
| 克雷伯 | 164 | 逐药预测列 + Kleborate 决定簇 | K_locus、O_locus、yv_acquired、Host sex |
| 淋球菌 | 99 | 逐药二值 + 决定簇二值 | NG-STAR TYPE、NG-MAST TYPE、AzithR1–R11 |
| 大肠埃希菌 | 86 | AMRFinderPlus 类别二值 | Source Niche、Uberstrain、Assembly barcode |
| 致泻性大肠埃希菌 | 约 86 | 同上 | 致泻型致病型分类 |
| 志贺 + EIEC | 88 | 同上 | 血清型与致病型 |
这张表最重要的信息是「耐药结果呈现方式」一列。伤寒与淋球菌给的是决定簇层(哪个基因、哪个位点),其余给的是 AMRFinderPlus 的类别层(这个类别下至少一个标记)。这两层的粒度差别,直接决定了你能回答什么问题:想回答「blaCTX-M-15 在这国的上升」,伤寒面板可以,非伤寒沙门面板不行,因为后者只有「头孢菌素类耐药」这个粗标签。
2.3 一条记录的完整解剖
把一条伤寒记录完整摊开,能看清版本、来源、采样与结果四层是怎么叠在一行里的。
Amrnet_id amrnet-st_1
Amrnet_version 1.1.0
Amrnetdb_date 22/05/2015 #-- 整库日期,非采样日期
NAME 343078_281186
DATE 2008 #-- 采样年份
COUNTRY_ONLY Bangladesh
TRAVEL local
TRAVEL ASSOCIATED No
SOURCE Blood
SYMPTOM STATUS Symptomatic
PURPOSE OF SAMPLING Targeted [AMR investigation]
ACCESSION ERR2663980
PMID 30425150
gyrA_S83Y 1 #-- 决定簇二值
cip_pred_pheno CipR
azith_pred_pheno AzithS
amr_category AMR_DCS
MDR 1
XDR 0
dfrA7 1
sul1 1
tetA(B) 1
num_amr_genes 4
GENOTYPE 4.3.1.3.Bdq
GENOTYPE_SIMPLE 4.3.1.3.Bdq
dashboard view exclude #-- 该行不进入地图合并估计
这一行几乎把本文要讲的问题全演示了一遍。第一,Amrnetdb_date 写的是 2015 年,采样年份是 2008 年,两者相差七年;如果把整库日期当成数据新鲜度,会严重误判。第二,这一行的采样目的是「Targeted [AMR investigation]」,即靶向耐药调查,最后 dashboard view 一列写的是 exclude。这就是这套系统最诚实的地方:它把被剔除的行保留在表里,只是打上标记,而不是悄悄删掉。使用者可以自己数一数有多少行被排除,从而知道面板展示的估计建立在多大的底座上。§4 的案例会展开说明这个标记为什么重要。
第三,MDR 这一列是 1 而不是字符串 MDR,而同一列在别的行里是「MDR」文本或「-」。这种编码不统一的情况在整表里存在(MDR 列同时出现 1、MDR 与 -),做聚合前必须显式归一,否则 pandas 会把这一列读成 object 类型,groupby 时静默出错。
2.4 字段的三种缺失形态
AMRnet 的缺失不是一句话能讲完的,至少有三类,处理方式完全不同。
| 缺失形态 | 出现位置 | 表现 | 正确处理 |
|---|---|---|---|
| 结构性缺失 | 某面板没有的字段 | 列不存在,不是空值 | 跨面板合并时前向填充等于造假 |
| 逻辑缺失 | TRAVEL 为 local 时的 TRAVEL_LOCATION | 值为单个短横线 | 应理解为不适用,不是未知 |
| 信息缺失 | SYMPTOM STATUS 的短横线、AGE 的空 | 值为短横线或空 | 是真正的未知,参与分层时必须单独成组 |
| 判定缺失 | amr_category 的 No AMR detected | 不是缺失,是一个有效结论 | 不可与空值混同处理 |
| 展示缺失 | dashboard view 的 exclude | 数据存在但不进入估计 | 做自建聚合时须自行决定是否沿用 |
这张表里最容易被做错的是「判定缺失」这一行。No AMR detected 是一个阳性结论——测了,没检出耐药决定簇;把它当成缺失丢掉,会让耐药比例被系统性高估,因为分母里少了那些最敏感的菌株。
2.5 与同类资源的字段差异
把 AMRnet 与几类常见资源放在一起看字段层面的分工,能更快判断该用哪个。
| 资源 | 行的含义 | 分子来自 | 分母的含义 | 层级 |
|---|---|---|---|---|
| AMRnet | 一株分离株(整理后) | 基因组决定簇 | 被公共测序的菌株数 | 菌株级 + 国家年度聚合 |
| Pathogenwatch | 一株分离株 | 基因组决定簇 | 使用者自己上传或检索的集合 | 菌株级,交互分析 |
| EnteroBase | 一株分离株 + 组装 | AMRFinderPlus | 该库收录的全部 | 菌株级 + 谱系聚类 |
| WHO GLASS | 一个监测点一年 | 实验室药敏试验 | 送检标本数 | 国家年度,表型 |
| 医院药敏年报 | 一个医院一年 | 实验室药敏试验 | 该院送检数 | 机构年度,表型 |
| SRA/ENA | 一次测序运行 | 无,需自行计算 | 无监测语义 | 原始读段 |
这张表最关键的一行是「分母的含义」。GLASS 的分母是送检标本,反映的是临床检验行为;AMRnet 的分母是被测序的菌株,反映的是科研与监测的测序行为。同样叫「耐药率」,两者的分母差着一整层筛选。这也是本文为什么反复强调分母:不是 AMRnet 特别不靠谱,而是基因组监测这个范式本身,分母就和传统监测不是同一个东西。
§3 它凭什么叫「监测」而不是「画图」
3.1 三道工序决定了它不只是可视化
把「可视化平台」四个字当真,会低估这套东西。它实际做了三件事,每件都改变了数字本身。
第一件是抽取与合并。它把 Pathogenwatch 和 EnteroBase 里分散在各个项目、各有各的元数据写法的分离株,映射到一套统一的字段上。这项工作听起来机械,实际上最难,因为「国家」这个字段在不同来源里可能指分离国、可能指患者国籍、可能指项目所在国。
第二件是规则化剔除。伤寒面板明确只保留来自非靶向采样框的分离株,即监测与疾病负担研究,而不是耐药专题研究或暴发调查。这一步是把分母的语义收紧——只保留那些「不论耐药与否都会被抽到」的样本。淋球菌面板做了类似的事,并注明纳入了 EuroGASP 2013 与 2018 以及若干国家监测研究。
第三件是门槛化展示。地图上只有样本数达到二十株的国家才出颜色。这个门槛本身就是一个统计学立场:少于二十株时,比例的抽样误差大到没有展示价值,宁可不显示也不显示一个不可靠的点。官方用法页写得很清楚,过滤后样本数不足二十株的国家会被涂成灰色,表示数据不足。
这三件事里,第二件和第三件是普通可视化工具不会做的。正是它们让 AMRnet 从「画图」变成了「带规则的聚合」。
3.2 门槛 20 的政治学
二十这个数字不是随便定的,但它也不是万能的。二十株的样本量,对一个比例估计来说,九成五置信区间宽得惊人:如果真实比例是三成,二十株里观察到三到九株都算正常。也就是说,即使过了门槛,两个国家一个显示三成、一个显示五成,也可能只是抽样波动。
这意味着地图的读法必须改变。地图上的颜色不是「这个国家的耐药率」,而是「这个国家被测序的菌株中,耐药比例的一个非常粗糙的点估计,且其置信区间通常与相邻色阶重叠」。把地图当热力图来找热点,会找到大量假热点。
平台自身没有在界面上展示置信区间,这是它的一个真实缺口。使用者在引用任何国家数字时,都应当自己用二项分布算一遍区间,或至少记住「二十株的估计很粗」。
3.3 加权合并到底加权了什么
官方用法页写地图数据是「按比例合并的加权估计」(pooled weighted estimates of proportion)。这句话没有说清权重从哪里来。在基因组监测的语境下,最自然的权重是样本量,即把某国某年所有符合筛选条件的菌株合并成一个比例。如果权重是样本量,那么「加权」与「直接合并」等价,这个词就只是描述性的。
这一点必须诚实标注为未核实:平台没有公开加权公式,API 文档也没有给出。使用者能确认的只有两件事:第一,地图的下载表里有分子、分母与百分比三列;第二,分母是过滤后的样本数。因此最稳妥的做法是不要依赖平台的百分比,而是下载分子分母自己算,这样权重口径就是你自己的,可复现。
3.4 与「耐药监测」这个词的距离
公共卫生语境下的耐药监测有几个隐含要求:连续、覆盖目标人群、有质量控制的实验室。AMRnet 满足第一个(各面板有连续年份),部分满足第二个(看国家,看是否整理过采样目的),完全不满足第三个(它没有做药敏,只有基因型预测)。
所以更准确的叫法是「基因组分母上的耐药流行率描述」。这不妨碍它有用,但妨碍它被当作监测报告直接引用。把这一点说清楚,比争论它算不算监测更有意义。
§4 数字的可信度:分母、偏倚与滞后
4.1 分母的三重含义
同一个「耐药率」在不同语境下有三个分母,混用会直接导致错误结论。
| 分母类型 | 定义 | 由谁提供 | 数量级直觉 |
|---|---|---|---|
| 病例分母 | 该国该年全部临床病例 | 疾病负担研究、哨点 | 最大 |
| 送检分母 | 该国该年送检做培养的标本 | 实验室监测网 | 中 |
| 测序分母 | 该国该年成功测序并进入公共库的菌株 | AMRnet 及各上游 | 最小 |
三者之间隔着两道筛选:从病例到送检,筛掉了不来就诊的人和不需要培养的人;从送检到测序,筛掉了没进测序项目的人。AMRnet 的分母是第三个,最小的那个。三道分母对应的耐药率通常依次升高,因为越往后筛,越偏向重症、越偏向耐药、越偏向被研究者关注的病例。
4.2 抽样偏倚:谁被送进了测序仪
进入测序仪的不是随机样本。几个已知的筛选方向:多重耐药菌更容易被送去做分子流行病学;暴发调查会集中测序一批;旅行相关病例因为要溯源而更容易被测;参考实验室的样本比基层医院更容易进库。
伤寒面板的采样目的字段把这些方向部分显式化了。整表里 Targeted 类占比不小,其中 Targeted [AMR investigation] 与 Targeted [Other] 两类合计有相当比例,而这些行大多被标为 exclude。换句话说,平台展示的估计是「剔除靶向采样之后」的结果,这比不剔除要可信得多。
即便如此,剩余的 Non Targeted 类里仍有细分:Surveillance Study、Reference lab、Routine diagnostics、Other。参考实验室的样本本身就带着选择性,因为送进参考实验室的病原往往是疑难或耐药标本。这一层偏倚平台没有再往下切,使用者若关心,可以自己按 PURPOSE OF SAMPLING 分层重算。
4.3 时间滞后:数据新鲜度的三个层次
「这份数据有多新」在 AMRnet 里至少要分三层问。
| 层次 | 看哪个字段 | 典型滞后 | 后果 |
|---|---|---|---|
| 快照生成时间 | S3 对象的最后修改时间 | 周级 | 影响你拿到的是哪一版 |
| 整库整理日期 | Amrnetdb_date | 与面板文档的更新日一致 | 影响整体收录范围 |
| 采样年份 | DATE | 多年,且各国不同 | 影响你对「当前耐药率」的判断 |
第三层是最要命的。一个面板的采样年份跨度可能有八十年(伤寒快照里最早的年份是 1935 年,最晚是 2021 年),但绝大多数记录集中在最近十几年。如果使用者不设年份筛选,直接看地图,得到的其实是「过去所有年份的合并」,而不是「最近一年」。平台提供了年份筛选,但默认视图未必是最近一年,使用者必须自己设。
4.4 基因组预测与真实药敏的系统性偏差
AMRnet 的分子是基因型预测,不是药敏。两者之间的差距有明确的方向性。
| 情形 | 基因型判断 | 真实表型 | 偏差方向 |
|---|---|---|---|
| 外排泵过表达 | 缺决定簇时不报耐药 | 可能耐药 | 低估 |
| 孔蛋白缺失 | 部分工具可判 | 常与 β-内酰胺耐药相关 | 视工具而定 |
| 低水平耐药(如低 MIC 环丙沙星) | 依阈值定义 | 临床判读可能为中介 | 视折点而定 |
| 沉默或截短的耐药基因 | 检出序列但无功能 | 敏感 | 高估 |
| 未知机制 | 无决定簇 | 可能耐药 | 低估 |
伤寒面板对环丙沙星的处理是个好例子:官方把「非敏感」定义为 MIC 大于等于 0.06 毫克每升,把「耐药」定义为 MIC 大于等于 0.5 毫克每升,并明确前者由 qnr 基因或 gyrA/parC/gyrB 突变导致、后者由多重突变与基因共同导致。这个定义把基因型与 MIC 阈值挂钩了,比单纯的「有决定簇就是耐药」要严谨。但这种严谨只在少数面板上做到,其余面板的类别标签(如 AMRFinderPlus 的 β-内酰胺类别)是机制归类,不等于临床耐药判定。
4.5 案例:一株被标为 exclude 的孟加拉国伤寒菌株
§2.3 解剖的那条记录来自孟加拉国,采样年份 2008 年,标本是血,症状是有症状,采样目的写的是 Targeted [AMR investigation],dashboard view 一列是 exclude。这一条记录,恰好能把本文的几条线索串起来。
第一,它说明了为什么 2008 年孟加拉国的数字看起来「偏高」。如果这样的靶向耐药调查记录被计入合并估计,该国当年的 MDR 比例会被抬高,因为进这类研究的菌株本身就是带着耐药假设被挑出来的。平台把这类行标为 exclude,从分母里剔掉,这是正确的做法,但也意味着展示出来的分母,比表里的总行数小。
第二,它说明了为什么「国家间差十倍」不能直接当生物学结论。假设甲国大量记录来自这类靶向调查且未剔除,乙国大量记录来自全国哨点的非靶向监测,那么甲国的绿色会深得多;而这个深浅差,与其说是菌株差异,不如说是采样框架差异。§2.3 的同一行还显示,这株菌的 GENOTYPE 是 4.3.1.3.Bdq,属于 H58 单倍型的一个分支,而 H58 本身就是与多重耐药扩散相关的一支。谱系构成差异会和采样框架差异叠加,让跨国比较更加不可靠。
第三,它说明了为什么使用者必须自己看 dashboard view 这一列。平台把剔除决策留在了数据表里,这是一个善意的设计,但它只在下载的 TSV 里可见,地图上看不到。只看地图的人,永远不会知道分母被削掉了一块;只有下载表的人,才能算出被削掉了多少。
第四,它还暴露了时间滞后的具体形态。这条记录在 2015 年的整库版本里,采样年份是 2008 年,PMID 指向一篇 2018 年发表的研究。也就是说,一株 2008 年的菌,等到被整理进库、再等到平台快照,中间隔了七八年。任何拿这个平台做「当前耐药形势」判断的人,都必须先接受这个时间尺度。
4.6 把偏倚做成一张可自查的清单
| 偏倚 | 在哪一层产生 | 平台是否已处理 | 使用者可做的补救 |
|---|---|---|---|
| 靶向采样偏倚 | 上游研究设计 | 伤寒、淋球菌已剔除,其余未 | 按 PURPOSE OF SAMPLING 分层重算 |
| 参考实验室偏倚 | 送样路径 | 未处理,仅可识别 | 剔除 Reference lab 子类做敏感性分析 |
| 旅行相关归属 | 元数据规则 | 已按旅行国归属 | 单列旅行相关做对照 |
| 年份构成差异 | 聚合方式 | 可通过筛选消解 | 固定年份窗口再比较 |
| 样本量不足 | 展示门槛 | 二十株以下置灰 | 自算二项区间,标注不确定性 |
| 基因型-表型偏差 | 决定簇判定 | 部分面板与 MIC 阈值挂钩 | 用有配对药敏的子集校准 |
| 谱系构成差异 | 生物学真实差异 | 不作处理 | 按谱系分层后再比较 |
这张表的价值在于,它把「偏倚」从一句空话变成了七条可操作的检查。每一条都对应平台上的一个字段或一个筛选动作,使用者不需要外部数据就能做大部分敏感性分析。
§5 取数与接入:三条路,各有各的坑
5.1 三条取数路径的取舍
| 路径 | 入口 | 是否需要密钥 | 适合场景 | 主要限制 |
|---|---|---|---|---|
| 面板下载按钮 | 各病原页面底部 | 否 | 一次性取某面板全量 TSV | 手动,无法自动化 |
| S3 快照 | amrnet.s3.amazonaws.com/amrnet-latest/ | 否 | 每周定时同步全库 | 文件较大,主键跨版本会变 |
| REST API | api.amrnet.org/api/v1 | 是,免费注册 | 按国家、年份、耐药变量取子集 | 有速率限制,需处理密钥 |
对绝大多数使用场景,S3 快照是最优解:无需密钥、无速率限制、文件已压缩、每周更新。API 适合做交互式查询或与其他系统集成。面板下载按钮适合在浏览器里临时取一次。
5.2 S3 桶的目录结构与命名规则
桶是公开只读的,前缀 amrnet-latest 下按病原各放一个压缩 CSV。命名规则很朴素:amrnetdb- 前缀 + 病原的英文写法,空格以短横线或下划线替代,后缀 .csv.gz。
| 面板 | S3 键名 |
|---|---|
| 伤寒 | amrnetdb-Salmonella_Typhi.csv.gz |
| 非伤寒沙门菌 | amrnetdb-Salmonella_enterica_nontyphoidal.csv.gz |
| 侵袭性非伤寒沙门菌 | amrnetdb-Salmonella_enterica_invasive_nontyphoidal.csv.gz |
| 肺炎克雷伯菌 | amrnetdb-Klebsiella_pneumoniae.csv.gz |
| 淋球菌 | amrnetdb-Neisseria_gonorrhoeae.csv.gz |
| 大肠埃希菌 | amrnetdb-Escherichia_coli.csv.gz |
| 致泻性大肠埃希菌 | amrnetdb-Escherichia_coli_ diarrheagenic.csv.gz |
| 志贺菌 + EIEC | amrnetdb-Shigella_EIEC.csv.gz |
这里有一个真实的坑:致泻性大肠埃希菌的键名里含一个空格(下划线与 diarrheagenic 之间),在 URL 里必须编码成 %20 才能取到。文档表格里显示为空格,直接拼接字符串会拿到 404。这不是官方文档写错,而是文件名本身带空格,使用者必须自己处理。
5.3 用 curl 拉一个面板并做基本核对
#-- 取伤寒快照(约半兆,几秒可下)
curl -O https://amrnet.s3.amazonaws.com/amrnet-latest/amrnetdb-Salmonella_Typhi.csv.gz
#-- 先看列数与前几列名,确认版本没变
zcat amrnetdb-Salmonella_Typhi.csv.gz | head -1 | tr ',' '\n' | wc -l
#-- 列出整个桶(XML 响应),核对是否新增了面板
curl -s "https://amrnet.s3.amazonaws.com/?list-type=2&prefix=amrnet-latest/"
#-- 取致泻性大肠埃希菌时注意文件名里的空格需编码
curl -O "https://amrnet.s3.amazonaws.com/amrnet-latest/amrnetdb-Escherichia_coli_%20diarrheagenic.csv.gz"
四条命令里第二条最有价值。它是你的版本哨兵:如果列数从一百零一变了一百一十,说明上游改了结构,下游脚本必须跟着改。
5.4 用 pandas 读进来并算出「分子除分母」
import pandas as pd
URL = "https://amrnet.s3.amazonaws.com/amrnet-latest/amrnetdb-Salmonella_Typhi.csv.gz"
df = pd.read_csv(URL, compression="gzip", low_memory=False)
#-- 版本哨兵:列名与记录数
print(len(df.columns), "columns", len(df), "rows")
#-- MDR 列同时存在 1 / MDR / - 三种写法,先归一
df["is_mdr"] = df["MDR"].astype(str).str.strip().isin(["1", "MDR"])
#-- 只保留进入面板估计的行
panel = df[df["dashboard view"].astype(str).str.strip() == "include"].copy()
#-- 按国家聚合:分子、分母、比例一次算齐
agg = (panel.groupby("COUNTRY_ONLY")
.agg(n=("is_mdr", "size"), mdr=("is_mdr", "sum")))
agg["prop"] = agg["mdr"] / agg["n"]
#-- 只保留达到展示门槛的国家,并按分母排序
agg = agg[agg["n"] >= 20].sort_values("n", ascending=False)
print(agg.head(15))
这段代码的核心不是算比例,而是那个 include 过滤。没有这一行,你算出来的分母会包含靶向采样行,与地图上看到的分母不一致,两边对不上时你会以为平台错了。
5.5 给比例加一个置信区间
from statsmodels.stats.proportion import proportion_confint
agg["lo"], agg["hi"] = proportion_confint(agg["mdr"], agg["n"], method="wilson")
#-- 看区间宽度:二十株附近的国家,区间通常宽得惊人
wide = agg.assign(width=agg["hi"] - agg["lo"]).sort_values("width", ascending=False)
print(wide[["n", "mdr", "prop", "lo", "hi", "width"]].head(10))
跑完这段,你就有了平台不提供、但比较时必须有的东西:区间。两个国家的区间重叠,就没有资格说「甲国比乙国耐药严重」。
5.6 调 API:先换一个密钥,再按国家查
API 需要免费注册取密钥。注册入口是 api.amrnet.org/api-register,密钥通过邮件发送。请求时把密钥放在 X-API-Key 头里,或作为 api_key 查询参数。
import os
import requests
BASE = "https://api.amrnet.org/api/v1"
KEY = os.environ["AMRNET_API_KEY"]
HEADERS = {"X-API-Key": KEY}
#-- 先列一遍病原,拿到每个面板的短名与当前记录数
orgs = requests.get(f"{BASE}/organisms", headers=HEADERS, timeout=30).json()
print(orgs)
#-- 再按国家与年份窗口取一个子集
r = requests.get(
f"{BASE}/organisms/styphi/resistance",
headers=HEADERS,
params={"country": "India", "year_from": 2018, "year_to": 2023},
timeout=30,
)
r.raise_for_status()
rows = r.json()["data"]
print(len(rows), "records")
#-- 全量导出走 download 端点,注意它限速更低
csv_text = requests.get(
f"{BASE}/organisms/styphi/download",
headers=HEADERS,
params={"format": "csv"},
timeout=120,
).text
API 的速率限制在文档里有明确数字:普通端点每个 IP 每秒三十次,允许五十次的突发;download 端点每秒两次,突发五次。做批量导出时,这两个上限会先撞到墙上,所以文档自己建议:需要全量就用 S3 快照,不要用 API。
5.7 接入时容易踩的四个技术坑
| 坑 | 表现 | 处理 |
|---|---|---|
| 文件名含空格 | 致泻性大肠埃希菌取到 404 | URL 编码为 %20 |
| 主键跨版本漂移 | 用 Amrnet_id 做 upsert 后行数暴涨 | 改用 ACCESSION 做业务键 |
| 混合类型列 | MDR 等列被读成 object | 显式归一后再聚合 |
| 缺密钥时的报错 | API 返回 401 与一段 JSON | 检查 X-API-Key 头是否带对 |
第二坑尤其值得说。Amrnet_id 的构造方式决定了它在面板内唯一,但不同快照之间同一株菌的编号可能变化,所以拿它做增量同步,会因为「每版都当新行」而导致重复堆积。用 ACCESSION 作为业务键,并在每个分区上打上快照日期,才是稳妥的做法。
5.8 DAIMS 二十四项检查
DAIMS 是一套面向「可持续交付的数据集」的检查清单,原名来自数据验收与信息管理规范。把它套在 AMRnet 上有意思的地方在于:它的多数扣分项不在平台自己做错了什么,而在它继承的上游分布。下表逐项给出判断,判断口径均以官方文档与快照表头为准。
| # | 检查项 | 状态 | 说明 |
|---|---|---|---|
| 1 | 宽表结构 | 是 | 每面板一张宽表,一行一株分离株 |
| 2 | 唯一标识 | 是 | Amrnet_id 面板内唯一,另有 ACCESSION 可跨库连接 |
| 3 | 字符规范 | 部分 | 主体为 ASCII,但存在带空格的文件名与混合类型列 |
| 4 | 重复控制 | 部分 | 克雷伯面板设 Duplicates 一列,其余面板未见到对应字段 |
| 5 | 缺失编码 | 否 | 短横线、空与 0 三种写法混用,无统一缺失码 |
| 6 | 标签可读 | 是 | 耐药类别与 MDR/XDR 标签有明确缩写表 |
| 7 | 罕见类合并 | 是 | 地图以二十株为门槛,天然抑制极小样本出数 |
| 8 | 偏倚声明 | 是 | 六个面板明确标注未做采样目的整理 |
| 9 | 数据字典 | 部分 | 有字段说明与缩写表,但无逐字段取值域表 |
| 10 | 缺失解释 | 部分 | 解释了短横线部分含义,未区分逻辑缺失与未知 |
| 11 | 测量记录 | 部分 | 记录上游工具与版本,不记录测序平台与读长 |
| 12 | 共线性说明 | 否 | 不讨论决定簇之间的共现与共线 |
| 13 | 编码映射 | 是 | 谱系与血清型采用社区标准方案 |
| 14 | 时间戳处理 | 部分 | 采样年份与整库日期分列,但无采集月日 |
| 15 | 划分建议 | 不适用 | 非机器学习数据集,无训练测试划分 |
| 16 | 泄漏讨论 | 不适用 | 同上 |
| 17 | 标签分布 | 否 | 平台不给逐字段分布,需自行统计 |
| 18 | 测量偏倚 | 是 | 明确说明基因型预测与药敏的差距 |
| 19 | 外部验证建议 | 是 | 要求同时引用上游数据源 |
| 20 | 版本记录 | 是 | 版本号与整库日期逐行附带 |
| 21 | 处理脚本 | 是 | 代码开源,安装指南公开 |
| 22 | 合规要求 | 是 | 软件 GPLv3,数据公开无凭证 |
| 23 | 多模态对齐 | 部分 | 单模态,靠 ACCESSION 与上游对齐 |
| 24 | 匿名化 | 不适用 | 病原菌株,不涉个人数据 |
计分口径按「是 1 分、部分 0.5 分、否 0 分、不适用剔除」:适用项二十个,得分为十四点五,折合约七十二分。这个分数的分布很能说明问题:凡是与「平台自己怎么做的」有关的条目(版本、标签、脚本、偏倚声明)几乎全满分;凡是与「上游数据长什么样」有关的条目(缺失编码、测量记录、标签分布)几乎全失分。这也印证了 §7.0 的前置校正——工程质量高,不能推及代表性好。
§6 与库内条目的关系
6.1 关系图谱:它在哪一层
库内与它相关的记录分成三圈。第一圈是上游基础库:ENA 与 SRA 存放原始读段,是所有基因组的上游;EnteroBase 与 Pathogenwatch 是它的直接上游。第二圈是同主题的表型监测:WHO 的 GLASS 体系、各国的药敏监测网、WHO 性传播感染流行率图谱,这些是「送检分母」一侧的资料。第三圈是知识与注释层:AMRFinderPlus 所依赖的参考基因目录、CARD 与 ResFinder 这类决定簇库、MLST 与 PubMLST 的谱系定义。
| 圈层 | 库内相关记录 | 与 AMRnet 的关系 |
|---|---|---|
| 原始数据 | ENA、SRA | 读段的最终来源,AMRnet 只到组装与决定簇层 |
| 上游整理 | EnteroBase(由 amrnet 面板上游指认) | 直接供数,含谱系聚类与血清型判定 |
| 表型对照 | WHO GHO、WHO 性传播感染流行率图谱、AMR-UTI | 提供「送检分母」与临床药敏一侧的证据 |
| 知识层 | AMRFinderPlus 参考目录、CARD、ResFinder、PubMLST | 决定簇与谱系的定义来源 |
| 测序平台 | Illumina 短读与 Nanopore 长读相关资源 | 决定组装质量,进而影响决定簇识别 |
| 患者级耐药数据 | MIMIC 系列的抗菌药使用字段、各院药敏记录 | 与本文的「国家年度层面」形成尺度对照 |
这张图的意义在于指明一个常见误解:很多人以为 AMRnet 可以直接替代 ENA 或 SRA。不能。AMRnet 是下游的下游,它建立在别人已经组装、已经注释的结果上;要改注释、要换决定簇库、要看新发现的基因,必须回到上游。
6.2 检索路径:三条常见问题该往哪走
| 你想知道 | 库内该查 | 在 AMRnet 上能做什么 |
|---|---|---|
| 某个耐药基因的序列与参考 | 参考基因目录、CARD、ResFinder | 只能看到它的有无,看不到序列 |
| 某国某病原的实验室药敏耐药率 | WHO GHO、GLASS 类记录、各国年报 | 只能看到基因组预测比例,可与表型率做对照 |
| 某个测序项目的原始读段 | ENA、SRA | 只能看到该项目整理后的汇总行 |
| 某菌的谱系定义与命名规则 | PubMLST、EnteroBase 文档 | 直接使用标准化后的谱系标签 |
| 某种耐药机制的结构基础 | PDB 与结构类资源 | 不涉及 |
检索路径的原则是:从 AMRnet 出发往上游走,能走到读段;从 AMRnet 往横向走,只能走到同类聚合,走不到临床。这一点决定了它在一份研究里的位置——它多半出现在「背景与方法」一节,而不是「结果」一节。
§7 质量评估与局限性
7.0 阅读本节前的一个前置校正
在给出评分之前,必须先纠正一个几乎人人都会犯的误判:把平台的「数据质量」与「数据代表性」混为一谈。AMRnet 的工程质量相当高——字段命名一致、版本化清晰、剔除决策留痕、三条取数路径都可用——但它的代表性受制于公共测序的分布,而代表性缺陷不是工程质量问题,是范式问题。用工程质量的高分去推断结论的代表性,是本节要拦下的第一类误判。
第二类误判是把「有整理」当成「已校正」。六个面板未做采样目的整理,两个做了;做了的那两个也只是剔除靶向研究,并没有做覆盖率加权或事后分层。因此即便在最好的面板上,国家间比较仍然带着覆盖率差异。
第三类误判是把「门槛二十」当成「样本足够」。二十株只是一个下限,用来挡住最离谱的估计,不是够用的标准。本节所有的评分都要在这个校正之后读。
7.1 五维评分
| 维度 | 权重 | 得分(满分 5) | 依据 |
|---|---|---|---|
| 可得性 | 20% | 5 | 网页、S3、API 三条路,前两条零门槛 |
| 结构规范度 | 20% | 4 | 字段命名一致、版本字段齐全;混合类型列与文件名空格扣分 |
| 可追溯性 | 20% | 4 | 每条记录带上游标识与文献钩子;不提供读段,回溯需一跳 |
| 代表性 | 25% | 2 | 分母是公共测序量,地理与病种覆盖极不均 |
| 时效性 | 15% | 3 | 每周快照但整库更新停在上一年,采样年份更早 |
加权总分约 3.55。这个分数不低,也不高,恰好反映它的真实位置:一个做得干净、但受制于上游数据分布的中间层。
7.2 与同类平台的逐项对比
| 对比项 | AMRnet | Pathogenwatch | EnteroBase | GLASS |
|---|---|---|---|---|
| 面向非专业用户 | 是 | 否 | 否 | 部分 |
| 给出分母 | 是 | 部分 | 是(库内全量) | 是(送检量) |
| 跨国可比性设计 | 有限(仅剔除靶向采样) | 无 | 无 | 有统一协议 |
| 表型数据 | 无 | 无 | 无 | 有 |
| 原始读段 | 无 | 无 | 无 | 无 |
| 更新频率 | 周(快照) | 持续 | 持续 | 年度 |
| 许可 | GPLv3(代码) | 视情况 | 视情况 | 公开报告 |
这张表里最值得注意的一行是「跨国可比性设计」。GLASS 之所以能跨国比,是因为有统一的病例定义、统一的药敏方法与统一的送检规则;AMRnet 没有这些,它只有「剔除靶向采样」这一道薄薄的校正。这不是它的失职,而是它选择的原料决定了它的上限。
7.3 已知的、可枚举的偏差
| 偏差 | 是否可识别 | 是否可在平台内校正 | 后果 |
|---|---|---|---|
| 靶向采样偏向耐药 | 是,有 PURPOSE OF SAMPLING 字段 | 部分,两个面板已剔除 | 未剔除面板的耐药率偏高 |
| 参考实验室样本偏向疑难 | 是,有 Reference lab 取值 | 可自行剔除 | 抬高比例 |
| 旅行病例归到旅行国 | 是,有 TRAVEL 与 TRAVEL_LOCATION | 可自行改判 | 分离国与来源国不一致 |
| 国家标签只到国家级 | 是,无亚国家级字段 | 不可 | 大国被压成一个点 |
| 无症状携带者缺失 | 部分,SYMPTOM STATUS 有取值 | 可分层 | 低估携带状态下的耐药 |
| 时间构成不均 | 是,有 DATE | 可设窗口 | 默认视图混多年 |
| 谱系构成差异 | 是,有 GENOTYPE | 可分层 | 与采样差异混淆 |
7.4 外部验证矩阵
要判断平台上的某国数字是否可信,除了自己算区间,还可以拿三类外部资料对照。
| 对照源 | 对照什么 | 能发现什么 | 局限 |
|---|---|---|---|
| WHO GLASS 国别报告 | 同类药物的表型耐药率 | 基因组预测与表型的整体偏离 | 药物与年份未必对齐 |
| 该国同行评议的基因组论文 | 同一菌同一国的比例 | 平台是否遗漏了某些队列 | 论文本身也有选择偏倚 |
| 上游 Pathogenwatch 原始视图 | 同一批分离株的计数 | 平台是否多算或漏算 | 上游视图不带面板筛选 |
| 该国实验室年报 | 送检量与分离量 | 测序覆盖率的真实分母 | 多数国家不公开 |
| 旅行医学文献 | 旅行相关病例的耐药构成 | 归属规则的影响 | 样本量小 |
其中最有价值的是第三行。把平台的分子分母与上游视图对一遍,能立刻看出整理规则削掉了多少,这是最接近「可复现」的验证方式。
7.5 它为何能持续:把整理成本摊给整个领域
这类平台最常见的死法是维护者毕业、经费到期、数据停更。AMRnet 能持续,靠的不是经费规模,而是把三项成本压到了很低:一是数据成本,不自己测序,只做下游整理;二是软件成本,代码开源、基于通用技术栈,任何人都能自建实例;三是信誉成本,与既有社区(伤寒基因组联盟、淋球菌专家顾问组、EnteroBase 与 Pathogenwatch 团队)捆绑,整理规则由社区维护而不由单个实验室重新发明。三项成本都低,平台的存续就不再依赖某一个人的时间。
§8 生态位与历史
8.1 从一张伤寒面板长到八张
AMRnet 的起点不是「全球耐药平台」,而是一个具体的伤寒仪表盘。官方文档写明,项目从 Salmonella Typhi 开始,基于此前的伤寒专用仪表盘,使用由伤寒基因组联盟整理、在 Pathogenwatch 中分析的数据。此后逐步加入肺炎克雷伯菌、淋球菌、非伤寒沙门菌、大肠埃希菌与志贺菌,形成今天八个面板的格局。官方还提到未来会加入更多病原,并计划在 2026 年把副伤寒甲纳入非伤寒面板。
这条路径解释了很多设计:为什么伤寒面板的字段最细(因为它是最早做的,也是唯一由联盟级整理驱动的),为什么淋球菌能拿到 EuroGASP 这类跨国监测数据(因为该病原本来就有成熟的国际合作网络),而其余面板只能吃 EnteroBase 的通用管线。
8.2 它在生态里的位置:中间那一层
| 层 | 代表 | 产出 | 谁用 |
|---|---|---|---|
| 原始层 | SRA、ENA | 读段 | 生信工程师 |
| 组装与注释层 | EnteroBase、Pathogenwatch | 组装、谱系、决定簇 | 研究者 |
| 聚合与展示层 | AMRnet | 国家年度合并估计 | 政策与公共卫生 |
| 决策层 | 国家行动计划、临床指南 | 政策与处方 | 决策者 |
AMRnet 占的是第三层。这一层的价值在于「翻译」,把第二层的技术产出翻译成第三层能读的语言。这一层也是最容易被误读的一层,因为翻译过程必然损失信息,而损失的部分往往是理解数字含义所必需的。
8.3 三个同类平台的定位差异
| 平台 | 解决的问题 | 与 AMRnet 的关系 |
|---|---|---|
| Pathogenwatch | 单株或单队列的基因组分析 | AMRnet 的上游,粒度更细 |
| EnteroBase | 大规模谱系聚类与血清型判定 | AMRnet 的上游,谱系定义的来源 |
| 伤寒专用仪表盘 | 单一病原的深度可视化 | AMRnet 的前身,仍在并行维护 |
第四个位置是「国家监测网」,但它们不做基因组,做表型,且往往不开放原始数据。AMRnet 与它们不是替代关系,是可以并列引用的两类证据。
8.4 一条时间线上该记住的几个点
| 时间 | 事件 |
|---|---|
| 项目起点 | 基于伤寒专用仪表盘,伤寒基因组联盟供数 |
| 扩张期 | 陆续加入克雷伯、淋球菌、非伤寒沙门、大肠、志贺 |
| 2025 年 8 月 5 日 | 各面板文档标注的最后更新日期 |
| 2025 年 11 月 | 论文在线发表 |
| 2026 年 1 月 | 论文进入数据库专刊正刊卷期 |
| 计划 | 副伤寒甲纳入非伤寒面板 |
这条时间线上最值得记住的是「2025 年 8 月 5 日」。它同时出现在多个面板文档与快照对象的时间戳里,是判断数据新鲜度的锚点。任何写「截至某年」的引用,都应该以这个日期为准,而不是以论文发表日期为准。
§9 使用指引
9.1 三种角色的路径
| 角色 | 最短路径 | 关键动作 | 常见错误 |
|---|---|---|---|
| 公共卫生分析人员 | 网页地图 → 导出 TSV → 自算区间 | 先设年份窗口,再看分母 | 直接截地图进报告,不写分母 |
| 流行病学研究者 | S3 快照 → pandas 分层 → 与文献对照 | 按采样目的与谱系分层 | 把国家当随机效应,忽略覆盖率 |
| 数据工程师 | S3 周同步 + ACCESSION 业务键 | 建版本哨兵与列结构断言 | 用 Amrnet_id 做增量 |
三类角色的共同点只有一个:都要先确认分母。区别在于,第一类人只需要在报告里写清楚,第二类人需要在分析里校正,第三类人需要在管道里保留。
9.2 一条最短的可用流程
#-- 1. 取伤寒快照,记录下载时刻用于版本留痕
curl -O https://amrnet.s3.amazonaws.com/amrnet-latest/amrnetdb-Salmonella_Typhi.csv.gz
date -u +"%Y-%m-%dT%H:%M:%SZ"
#-- 2. 列数哨兵:预期 101,变了就停下来看变更
zcat amrnetdb-Salmonella_Typhi.csv.gz | head -1 | tr ',' '\n' | wc -l
#-- 3. 行数与被排除行数,一次看清基础盘
zcat amrnetdb-Salmonella_Typhi.csv.gz | wc -l
zcat amrnetdb-Salmonella_Typhi.csv.gz | grep -c ',exclude$'
import pandas as pd
from statsmodels.stats.proportion import proportion_confint
df = pd.read_csv("amrnetdb-Salmonella_Typhi.csv.gz", low_memory=False)
df["year"] = pd.to_numeric(df["DATE"], errors="coerce")
df["inc"] = df["dashboard view"].astype(str).str.strip() == "include"
df["mdr"] = df["MDR"].astype(str).str.strip().isin(["1", "MDR"])
#-- 固定一个年份窗口,避免把不同年代混在一起
win = df[df["inc"] & df["year"].between(2015, 2020)]
tab = win.groupby("COUNTRY_ONLY").agg(n=("mdr", "size"), k=("mdr", "sum"))
tab = tab[tab["n"] >= 20]
tab["p"] = tab["k"] / tab["n"]
tab["lo"], tab["hi"] = proportion_confint(tab["k"], tab["n"], method="wilson")
print(tab.sort_values("p", ascending=False).head(20).round(3))
两段加起来就是一条可以每天跑的最小管道:拿数、验结构、设窗口、算比例、加区间。任何在报告里出现的国家数字,都应当能由这条管道复现。
9.3 引用方式
引用本平台时,官方给出的规范是引用论文:Cerdeira LT、Dyson ZA、Sharma V 等,AMRnet: a data visualization platform to interactively explore pathogen variants and antimicrobial resistance,Nucleic Acids Research,DOI 10.1093/nar/gkaf1101。官方还要求同时引用所查询病原对应的上游数据源,这一点常被忽略,但很重要——因为分子与分母的语义都由上游决定,只引平台而不引上游,等于引了一个二手结论。
| 引用场景 | 该引什么 | 补充 |
|---|---|---|
| 引用平台方法 | 上述论文 | 说明版本与访问日期 |
| 引用某国数字 | 论文 + 上游来源(Pathogenwatch 或 EnteroBase) | 写明分母与年份窗口 |
| 复用代码自建实例 | 论文 + GPLv3 许可声明 | 保留版权与许可全文 |
| 教学演示 | 论文 + 平台网址 | 提醒学生看 dashboard view 列 |
§10 AI 使用声明
| 项目 | 说明 |
|---|---|
| 本文写作方式 | 人类设定主轴与章节骨架,语言模型协助组织与扩写 |
| 事实来源 | 官方文档页、官方 API 与 S3 响应、Europe PMC 论文摘要三处,链接见附录 C |
| 数字核验 | 规模类数字取自快照行数与字段数,结构类取自文档与表头,边界类取自官方警示 |
| 未核实项 | 加权公式、各面板地理分布细节、上游版本号变化历史 |
| 未做的事 | 未对全库做分布统计,未下载全量十兆级以上的面板逐条审计 |
| 语言模型用途 | 结构建议、措辞修改、表格整理;不含事实生成 |
| 已知局限 | 快照每周更新,文中规模数字会随时间过期,以附录 A 的取数日期为准 |
| 使用建议 | 引用任何数字前,按 §9.2 的流程自行复现一次 |
常见误读(避坑清单)
| 常见说法 | 实际 | 证据 |
|---|---|---|
| 「AMRnet 是一个全球耐药率数据库」 | 它是基因组预测比例的聚合,不是药理表型率 | 论文摘要:数据来自公共基因组库,做合并估计 |
| 「地图上灰色表示该国没有耐药」 | 灰色表示过滤后样本不足二十株 | 官方用法页:N≥20 才出数,否则置灰 |
| 「两国颜色深浅之差就是耐药之差」 | 差异混着测序覆盖率、采样目的、年份构成 | §4.6 的偏倚清单第一行 |
| 「所有面板都做过采样目的整理」 | 只有伤寒与淋球菌做了,其余六个官方标注未整理 | 各面板页面的 Warning 段落 |
| 「下载全量数据要注册」 | S3 与面板按钮都不需要,只有 API 需要免费密钥 | 官方数据访问页的三条路径 |
| 「数据是每周更新所以很新」 | 快照每周重发,但整库整理日期停在 2025 年 8 月 5 日 | 面板文档的 Last update 与快照时间戳 |
| 「它自己测序」 | 官方明确说不生成序列数据 | 文档首页原话 |
| 「No AMR detected 是缺失值」 | 它是「测了、没检出」的有效结论,删掉会高估耐药 | 伤寒表 amr_category 取值 |
| 「靶向耐药调查的记录已经删掉了」 | 记录仍在表里,只是标记为 exclude | 伤寒表 dashboard view 列 |
| 「可以用它训练耐药预测模型」 | 无读段、无组装质量、只有结论列 | 官方数据页只给 TSV 与 CSV |
FAQ
Q1:AMRnet 自己测序吗?
不测。官方文档写明它不生成序列数据,只把公共库中已有的基因组结果整理后可视化,上游是 Pathogenwatch 与 EnteroBase。
Q2:地图上某个国家是灰色,说明该国没有耐药吗?
不是。灰色表示在当前筛选条件下该国样本数不足二十株,官方不展示合并估计,因此灰色是数据空缺而非耐药为零。
Q3:可以直接拿两个国家的流行率做减法比较吗?
不能。两国测序覆盖率、抽样目的、年份构成都不同,差异里混杂了分母差异,平台本身不提供跨国的显著性检验。
Q4:下载全量数据需要注册吗?
走 S3 快照不需要注册也不需要密钥;走 REST API 需要免费注册取得密钥,并在请求头里带上。
Q5:可以把它当作实验室药敏结果的替代吗?
不能。平台给的是基因型预测,与真实药敏存在系统性偏差,临床决策必须以培养与药敏试验为准。
Q6:为什么不同面板的字段数差那么多?
因为上游不同。伤寒与淋球菌来自 Pathogenwatch 的病原专用管线,克雷伯走 Kleborate 所以逐药预测各占一列,大肠、志贺与非伤寒沙门走 AMRFinderPlus 的类别归纳,列更少。
Q7:旅行相关病例算在哪个国家?
按官方规则归属到旅行国,而不是分离国。表里同时有分离国与旅行国字段,需要改判时自己重算。
Q8:为什么表里还有被排除的行?
因为平台把剔除决策留痕,而不是删行。使用者可以据此算出自建口径下的分母,也能验证平台的排除规则。
Q9:快照多久更新一次,能拿来做时间序列监测吗?
快照每周重发,但收录的采样年份滞后多年,拿它做「当前形势」的时间序列会失真;做长期趋势可以,做月度监测不行。
Q10:能不能用它做机器学习的训练集?
不建议。它给的是已经算好的结论列,没有读段与质量指标,训练出来的是对别人结论的拟合,学到的是注释规则而不是序列规律。
Q11:代码许可是什么,能自建实例吗?
软件侧是 GPLv3,官方提供安装指南;数据侧平台汇总库公开下载,上游来源与 EnteroBase 各自条款另算。
Q12:用它的时候最少要引用什么?
至少引用方法论文,并按官方要求同时引用所查病原对应的上游数据源,写明版本与访问日期。
术语表
| 术语 | 英文 | 在本平台语境下的含义 |
|---|---|---|
| 抗菌素耐药 | AMR(Antimicrobial Resistance) | 病原对药物不敏感的现象,本平台以基因型代理 |
| 全基因组测序 | WGS | 病原基因组完整测序,本平台的上游原料 |
| 决定簇 | determinant | 导致耐药的基因或突变,二值化为有/无 |
| 分离株 | isolate | 一次培养得到的一株菌,本平台的一行 |
| 面板 | dashboard | 按病原划分的一套可视化与数据表 |
| 分母 | denominator | 该格子里参与计算的菌株数,即测序覆盖量 |
| 合并估计 | pooled estimate | 把多来源样本合成一个比例 |
| 非靶向采样 | non-targeted sampling | 不论耐药与否都会被抽到的抽样框架 |
| 靶向采样 | targeted sampling | 因耐药或暴发而专门抽取的样本 |
| 采样目的 | purpose of sampling | 表里的用途字段,决定该行是否进入估计 |
| 最低抑菌浓度 | MIC | 抑制细菌生长的最低药物浓度,本平台用于阈值定义 |
| 非敏感 | non-susceptible | 介于敏感与耐药之间,定义依赖阈值 |
| 多重耐药 | MDR | 对若干一线药物同时耐药,定义按病原不同 |
| 广泛耐药 | XDR | 在 MDR 基础上再叠加,定义按病原不同 |
| 超广谱 β-内酰胺酶 | ESBL | 水解头孢菌素的酶类,按决定簇推断 |
| 碳青霉烯酶 | carbapenemase | 水解碳青霉烯类的酶,按决定簇推断 |
| 谱系/基因型 | lineage / genotype | 按 SNPs 与 MLST 划分的菌株归属 |
| 序列型 | ST | 七位点 MLST 的分型编号 |
| 核心基因组序列型 | cgST | 基于核心基因组的更细分型 |
| H58 | H58 | 伤寒中与多重耐药扩散相关的优势单倍型 |
| 打字方案 | typing scheme | 如 MLST、NG-MAST、NG-STAR、GenoTyphi |
| 质粒复制子 | Inc type | 质粒不相容群,与耐药基因的水平转移相关 |
| 快照 | snapshot | 定期发布的压缩 CSV 全量文件 |
| 速率限制 | rate limit | API 的每秒请求上限 |
| 数据访问密钥 | API key | 免费注册取得,用于 API 鉴权 |
| 交付格式 | TSV / CSV.gz / JSON | 三条取数路径各自的格式 |
| 基因型-表型偏差 | genotype-phenotype gap | 预测与实际药敏之间的系统性差异 |
附录 A:核心数字核对表
| 项 | 值 | 来源 | 来源层级 |
|---|---|---|---|
| 病原面板数 | 8 | 官方文档病原页与数据访问页 | 官方页面 |
| 伤寒面板字段数 | 101 | 快照表头计数 | 官方页面(S3) |
| 克雷伯面板字段数 | 164 | 快照表头计数 | 官方页面(S3) |
| 大肠埃希菌面板字段数 | 86 | 快照表头计数 | 官方页面(S3) |
| 志贺面板字段数 | 88 | 快照表头计数 | 官方页面(S3) |
| 伤寒面板记录数 | 14,099 | S3 快照记录计数 | 官方页面(S3) |
| 淋球菌面板记录数 | 29,364 | S3 快照记录计数 | 官方页面(S3) |
| 大肠埃希菌面板记录数 | 41,249 | S3 快照记录计数 | 官方页面(S3) |
| 志贺面板记录数 | 49,094 | S3 快照记录计数 | 官方页面(S3) |
| 克雷伯面板记录数 | 31,854 | S3 快照记录计数 | 官方页面(S3) |
| 地图展示门槛 | N≥20 | 官方用法页 | 官方页面 |
| 面板最后更新日 | 2025-08-05 | 多个面板文档与快照时间戳 | 官方页面 |
| API 普通端点限速 | 30 次/秒 | 官方数据访问页 | 官方页面 |
| API 下载端点限速 | 2 次/秒 | 官方数据访问页 | 官方页面 |
| 软件许可 | GPLv3 | 文档许可页与仓库 LICENSE | 官方页面 |
| 论文 DOI | 10.1093/nar/gkaf1101 | Europe PMC | 论文摘要 |
| 论文发表年 | 2026 | Europe PMC 卷期信息 | 论文摘要 |
| 作者首作者 | Cerdeira LT | Europe PMC | 论文摘要 |
附录 B:数字的来源分层
| 层级 | 包含什么 | 本文中的例子 | 处理方式 |
|---|---|---|---|
| 官方页面 | 文档、面板页、数据访问页、API 文档、S3 响应 | 八面板、字段数、门槛二十、限速、许可 | 直接引用,写明日期 |
| 论文摘要 | Nucleic Acids Research 摘要 | 定位、上游来源、整理目的、动态报告与 API | 只用于定位与动机,不用于规模数字 |
| 未核实 | 加权公式、地理分布、上游版本变更史 | 加权方式 | 文中明确标注「未核实」,不填数字 |
三层的界线必须守:规模数字只从官方页面取,动机与定位只从摘要取,两者都不覆盖的,留空标注,不猜。
附录 C:完整参考文献
附录 D:任务代码
这个脚本把核心理念做成了一个可重复的动作:拿数据、留痕、验结构、算分母、导出。
import json
import hashlib
from datetime import datetime, timezone
import pandas as pd
import requests
BUCKET = "https://amrnet.s3.amazonaws.com/amrnet-latest"
PANELS = {
"styphi": "amrnetdb-Salmonella_Typhi.csv.gz",
"ngono": "amrnetdb-Neisseria_gonorrhoeae.csv.gz",
}
EXPECTED_MIN_COLS = 80
def fetch(key):
r = requests.get(f"{BUCKET}/{key}", timeout=180)
r.raise_for_status()
return r.content
def run(short, key):
blob = fetch(key)
digest = hashlib.sha256(blob).hexdigest()[:12]
open(key, "wb").write(blob)
df = pd.read_csv(key, compression="gzip", low_memory=False)
#-- 结构断言:列数骤降意味着上游改了表,不要继续算
assert len(df.columns) >= EXPECTED_MIN_COLS, f"{short} 列数异常 {len(df.columns)}"
df["year"] = pd.to_numeric(df["DATE"], errors="coerce")
inc = df["dashboard view"].astype(str).str.strip() == "include"
out = df[inc & df["year"].between(2015, 2020)]
tab = out.groupby("COUNTRY_ONLY").agg(n=("year", "size"))
tab = tab[tab["n"] >= 20]
return {
"panel": short,
"fetched_utc": datetime.now(timezone.utc).isoformat(timespec="seconds"),
"sha256_12": digest,
"cols": len(df.columns),
"rows": len(df),
"included": int(inc.sum()),
"countries_ge20": int(len(tab)),
}
report = [run(k, v) for k, v in PANELS.items()]
print(json.dumps(report, ensure_ascii=False, indent=2))
脚本里的三个设计都是针对文中提到的问题:sha256 前十二位是版本指纹,保证你能复现同一份输入;列数断言是结构哨兵,防止上游改表后静默出错;included 计数把「分母被削掉多少」直接写进报告,让每次运行的底座可见。
附录 E:如果只记五件事
第一,它是翻译层,不是数据源。它不测序,只把上游的结果翻译成能读的形式。
第二,它的分母是测序量,不是病例数。任何引用都必须带「在测序菌株中」这个限定。
第三,地图上的灰色是数据不足,不是耐药为零;二十株是下限,不是够用标准。
第四,八个面板里只有两个做过采样目的整理,其余六个的耐药率系统性偏高。
第五,它的快照每周更新,但整库整理停在上一年八月,拿它做当前形势判断会失真。
附录 F:三种常见的测算误区与正确写法
附录 A 到 E 讲的是「数字从哪来」,本附录讲「数字怎么被用错」。这三条误区在实际写作与政策简报里出现频率最高,每一条都给出错误写法与正确写法,便于直接对照修改。
| 误区 | 错误写法 | 为什么错 | 正确写法 |
|---|---|---|---|
| 分母替换 | 「该国耐药率百分之六十二」 | 分母是测序菌株,不是全部病例 | 「在该国进入公共库的测序菌株中,耐药者占六成二」 |
| 跨国直接比较 | 「甲国耐药率是乙国的两倍」 | 两国覆盖率与抽样目的一致才可比 | 「两国数字差异不可直接相减,须先比对分母与抽样框架」 |
| 时间点错配 | 「截至今年,该国耐药持续上升」 | 平台收录的采样年份滞后多年 | 「截至平台最后一次整库整理,该国最近可用年份为某年」 |
三条误区的共同点是都省略了限定语,而限定语恰恰承载了全部信息。写作时可遵循一条经验规则:凡是出现比例数字的句子,句子里必须同时出现分母的说明;做不到,就把数字删掉,只留定性判断。
编辑说明
本篇的核验时间为 2026 年 10 月 26 日。核验方式:抓取官方文档总览、数据访问、用法、病原总览与四个面板页的 HTML;读取公开 S3 桶的文件列表与前若干面板的表头与行计数;请求 API 根路径确认鉴权行为;从 Europe PMC 取论文摘要。未做的事:未对全库做分布统计,未下载十兆级以上的面板逐条统计,未验证加权公式(官方未公开)。文中规模数字对应快照的生成时间为 2025 年 8 月上旬,此后官方若重发快照,数字会变动,以附录 A 的取数日期为准。
相关数据集导航
以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:
- gbd-results — 共享标签:公共卫生与流行病学 / 疾病监测 / 全球健康
- gho-steps — 共享标签:公共卫生与流行病学 / 疾病监测 / 全球健康
- era5-single-levels — 共享标签:公共卫生与流行病学 / 疾病监测 / 全球健康
- oisst-v2-1 — 共享标签:公共卫生与流行病学 / 疾病监测 / 全球健康
- ibtracs — 共享标签:公共卫生与流行病学 / 疾病监测 / 全球健康
- argo-gdac-floats — 共享标签:公共卫生与流行病学 / 疾病监测 / 全球健康
- sth-schisto-eggs — 共享标签:公共卫生与流行病学 / 疾病监测 / 全球健康
- who-sti-prevalence-atlas — 共享标签:公共卫生与流行病学 / 疾病监测 / 全球健康
- who-mortality-db — 共享标签:公共卫生与流行病学 / 疾病监测 / 全球健康
- ctd — 共享标签:基因组学与多组学 / 公共卫生与流行病学 / 疾病监测
导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

