GBD数据BAPC分析:R包实现疾病负担年龄-时期-队列预测
2026/9/2 2:26:32 网站建设 项目流程

简介:面向使用 R 语言分析全球疾病负担(GBD)数据库的科研人员与公共卫生从业者,尤其适合需要借助贝叶斯年龄-时期-队列(BAPC)模型研究疾病长期趋势、有一定统计基础并希望直接上手真实数据的读者。资源以 Nordpred 等 R 包为核心,共 41 个文件,包含 R 源代码、Rd 帮助文档、rda 示例数据、Rmd 构建脚本和 README 说明,目录按 R 包规范组织,压缩包仅 57KB,体量轻巧却覆盖了从数据处理、模型估计到结果绘图的完整流程。目前已有 2083 人学习下载,可作为 BAPC 分析的入门参考与二次开发基础。通过源码和内置数据,可以掌握年龄、时期、队列效应的分解逻辑,熟悉发病率与死亡率预测的实现方法,并复用数据整理、模型估计、绘图展示等核心代码,为后续开展真实 GBD 数据研究节省大量摸索时间。 GBD(Global Burden of Disease)数据库下载下来的结果动辄几万行,绝大多数做疾病负担分析的人第一步都是画几张年龄趋势图、算个joinpoint回归斜率,但一旦到了“预测未来几年疾病负担会怎么变化”这一步,网上能直接抄的成熟方案就少了很多。我刚开始用BAPC分析GBD数据时,光是安装依赖包就折腾了很久,后来把模型跑通、结果也解释清楚了,才发现这套方法其实没有想象中那么神秘,真正卡人的地方反而都在数据格式和包环境上。

这篇就分享我在GBD数据库上做BAPC分析时用到的R包、完整操作流程,以及那些文档里不会写的坑。如果你已经下载过GBD数据、会用一点R,又想做趋势预测或年龄-时期-队列分解,这篇文章应该能帮你少走不少弯路。

1. GBD数据集与BAPC的天然契合点

1.1 GBD数据到底长什么样

GBD是全球疾病负担研究(Global Burden of Disease Study)的缩写,由IHME维护,覆盖了204个国家和地区的371种疾病和伤害、88种风险因素,几乎所有指标都按地区、年份、年龄、性别做了分层。因为它是模型估计值而不是单纯的医院登记数据,所以每个数值还自带上限和下限,也就是95%不确定性区间(UI)。

下载方式是在IHME官网进入GBD Results Tool,按需求选择measure(死亡数、发病数、患病数等)、cause、location、age group、year、metric(number或rate),然后导出CSV。这里有一个很重要的习惯:数据年份尽量拉长,至少要有20年以上的连续年份,否则后面模型对时期效应的估计会非常不稳。年龄组则在下载时直接选标准5岁年龄组,能省很多后期处理的功夫。

GBD这份数据结构和BAPC模型的输入结构几乎是天然对齐的——模型要的就是按年份、年龄、性别分层的事件数或率。换句话说,GBD数据本身就是为年龄-时期-队列分析准备的,只是多数人下载后只做了描述统计,没有继续往下走模型。

1.2 BAPC模型解决的核心问题

BAPC(Bayesian Age-Period-Cohort analysis)把时间维度拆成三个方向的效应。年龄效应反映的是生命历程里风险随年龄的变化,比如多数癌症的发病风险随年龄上升;时期效应反映的是某个日历年份对所有年龄段的同步影响,比如某一年筛查技术普及导致检出率整体上升;队列效应则指同一年代出生的人群共同经历的风险暴露,比如某几个年代出生的人恰好赶上了某种生活习惯的变化。

这三个量之间有一个天然关系:cohort = period - age。所以年龄、时期、队列并不是三个独立变量,直接用普通回归模型会产生完全共线性问题,这正是经典APC模型无法直接估计的根源。BAPC的解决办法是给三个方向的效应加上随机游走先验,利用贝叶斯推断把模型跑起来,同时顺带给出预测值的不确定性区间。

BAPC背后的计算引擎是INLA(Integrated Nested Laplace Approximations),它比传统的MCMC采样快得多,不需要手动调采样器和判断收敛,跑一个常规GBD子集数据通常几分钟到十几分钟就能完事。这也是我推荐直接从BAPC入手而不是自己写贝叶斯抽样代码的原因。

2. 这一套分析需要用到的R包清单

2.1 计算核心:BAPC + INLA

整个流程里的绝对主角是BAPC包,它封装了从数据对象转换、APC模型拟合到结果绘图的全套功能,适合不熟悉贝叶斯细节、又想用APC模型做预测的人。BAPC底层依赖INLA来做贝叶斯计算,所以这两个包必须一起装,缺一不可。

安装时要特别注意,INLA不在CRAN上,直接用install.packages("INLA")会失败。正确做法是从INLA官方仓库安装:

install.packages("INLA", repos = c(INLA = "https://inla.r-inla-download.org/R/stable/"))

BAPC则可以直接从CRAN安装:

install.packages("BAPC")

装好之后,每次使用前同时加载:

library(BAPC) library(INLA)

这两个包的版本兼容性是我踩过最大的坑之一,后面第4章会详细说。

2.2 数据整理与可视化辅助包

除BAPC和INLA之外,整个流程里还需要一批辅助包来搞定数据清洗和结果展示,大多数都是R里常用的老面孔:

  • readr / readxl:读取CSV或Excel格式的GBD下载结果。
  • dplyr + tidyr:做数据筛选、分组汇总、长宽格式转换。
  • reshape2:老牌的宽表转长表工具,dcast和melt函数在处理GBD这种“年份×年龄组×性别”交叉表时非常好用。
  • stringr:处理年龄组文本(比如把"5-9 years"拆成数字5)。
  • ggplot2:出论文级图表,把BAPC的默认图形重绘成更容易放进文章里的形式。

这些包本身没什么门槛,但有一个分工意识很重要:GBD下载的原始表往往是宽格式,比如每一个年份一行、每个年龄组一列,而BAPC需要的是长格式,每行必须是“年份 + 年龄 + 性别 + 数值”这样的一条记录,而且不同性别要显式标出来。这个长宽转换就是整个流程里最容易出错一步。

3. 一次完整实操:从GBD表格到预测图

3.1 预处理:性别拆分、年龄组对齐、长宽格式转换

假设你从GBD Results Tool下载了某疾病1990到2021年、某地区的死亡人数(Number),数据表里每一行包含location、year、age group、sex、val等列。第一步先做清洗:

library(dplyr) library(tidyr) # 假设df是从GBD下载的原始数据 df <- df %>% filter(location_name == "某国") %>% # 选中目标地区 select(year, age_group, sex, val) # 只需要这几列 # 把年龄组文本转成数字起点,例如"5-9 years"转成5 df$age_start <- as.numeric(sub("-.*", "", df$age_group)) # 确保年份是数值型 df$year <- as.numeric(df$year)

这中间有一个必须处理的细节:GBD下载的年龄组里包含"<1 year"、"1-4 years"、"5-9 years"一直到"95+ years",如果你要做标准5岁年龄组,需要先把"<1 year"和"1-4 years"合并成"0-4 years"这一组。理由很直接——BAPC要求年龄组等宽,只有最后一组可以是开放的(如85+),中间混入一个1岁以下组和1-4岁组,实际上是把年龄轴压缩了,模型跑出来的年龄效应会有畸变。

处理完年龄组后,把宽表转成长表,并确认数据里没有缺失值:

# 如果有宽表需要转长表,用reshape2 library(reshape2) df_long <- melt(df_wide, id.vars = c("year", "sex"), variable.name = "age_group", value.name = "count") # 剔除缺失值,BAPC不允许NA存在 df_long <- df_long[complete.cases(df_long), ]

3.2 建模:创建APC对象与运行BAPC

数据清洗完成之后,就可以进入BAPC的核心流程了。BAPC包提供了一个示例数据集ICD,新手可以先拿它把整套流程跑通,再替换成自己的数据。

library(BAPC) library(INLA) # 跑一遍自带示例数据,确认环境没问题 data(ICD) str(ICD) # 看看自带数据的结构:year、age、sex、count # 将数据框转换为AgePeriodCohort对象,agegroup指定为5岁年龄组 apc <- as.AgePeriodCohort(ICD, agegroup = "5y") # 拟合完整APC模型,并预测未来15年 fit <- BAPC(apc, model = "APC", predict = list(npredict = 15)) # 查看结果概况 summary(fit) # 绘图 plot(fit)

这段代码虽然短,但背后做的事情并不少。as.AgePeriodCohort会把你的长格式数据重构为模型要求的年龄-时期矩阵;BAPC内部会调用INLA去拟合带随机游走先验的APC模型;predict参数里的npredict控制向前预测的年数。

有一点要注意:BAPC函数中model可以设置成"APC"、"AP"、"AC"或"PC",不同模型对应不同的效应组合。实际分析时不要盲目选完整模型,可以都跑一遍,对比DIC(偏差信息准则)选更合适的。比如队列效应不明显时,AP模型往往更稳定。

3.3 看图与读结果

plot(fit)跑出来的默认图形包含多块内容,最核心的是年龄效应、时期效应、队列效应的后验估计曲线,以及历史拟合和未来预测的总曲线。看懂这三条曲线,基本就明白BAPC能给GBD数据分析带来什么了。

年龄效应的曲线如果单调上升,说明这个疾病的风险主要随年龄积累,比如多数退行性疾病和癌症。时期效应的曲线如果出现明显的台阶或转折,往往对应某个时间节点上的筛查普及、诊断标准变化或治疗革命。队列效应则是看哪一批出生年份的人群风险更高,通常用于回溯环境暴露或生活习惯的代际差异。

预测结果里,我最推荐先看预测曲线的置信区间宽度。如果区间在几年之内就宽到跨数量级,说明数据支撑力不足,要么缩短预测年数,要么考虑换更简洁的模型。如果区间相对稳定且窄,预测值才有直接引用到报告里的价值。

4. 我踩过的那些坑及排查思路

4.1 INLA安装:最折磨人的第一关

我第一次装INLA时直接用了install.packages("INLA"),结果CRAN上根本没有这个包。后来从网上搜到要用官方repos安装,但又因为R版本和INLA版本不匹配,加载的时候直接报错。

这类问题的排查思路是:先确认R版本,然后去INLA官网的repos页面看哪个版本的INLA支持当前R版本。stable分支是稳定版,testing分支是测试版,建议先用stable,测试版虽然功能新但容易出现和BAPC不兼容的情况。

另外,Windows用户千万不要从源码编译INLA,不然大概率卡在Rtools配置上。直接从官方repos装二进制包,一分钟搞定。装完以后用requireNamespace("INLA")检查一下能否正常加载,再做下一步。

4.2 数据格式坑与典型报错

BAPC对数据格式的要求比大多数R包都严格,我整理一下最常见的几类报错和对应的解决思路。

第一类报错是“age groups must be of the same size”,意思是年龄组必须等宽。GBD原始年龄组里包含1岁以下和1-4岁这种非等宽组,必须提前合并成0-4、5-9这种结构。合并方法是用dplyr的mutate手动映射年龄组,或者直接按age_start区间重分组。

第二类报错是某个年龄组没有任何数据,比如某一年龄组全为0或全为NA,BAPC在执行转换时会中断。解决办法是把缺失的组合补0,或者干脆把那个年龄组删掉,但前提是删掉后不影响年龄轴的连续性。

第三类问题是因子水平顺序错乱。如果你的sex列不是一个factor,BAPC可能把男女当成数值处理,结果完全跑偏。建议提前显式设置因子水平:

df_long$sex <- factor(df_long$sex, levels = c("Male", "Female"))

4.3 预测结果的合理性校验

模型跑出来不代表就能直接用了。我习惯在拿到预测结果后做三件事验证合理性。第一,把历史年份的模型拟合值叠到原始观测值上,如果拟合值和实际值的差距肉眼可见地大,说明模型本身选得不对。第二,看预测的第一年是否和历史最后一年的值平滑衔接,如果出现明显跳崖,通常是因为period效应和cohort效应在某一年产生了冲突。第三,把预测区间宽度和时间长度画在一张图里,观察是否随预测年份线性扩宽,如果区间在某一年突然收紧,大概率是数值计算出了问题。

还有一个很多人忽略的点:2020到2021年受重大公共卫生事件影响,很多疾病的死亡趋势出现了异常波动。GBD 2021最新数据里这自然包含在内。如果做BAPC预测,建议在敏感性分析里对比一下“包含这两年和截断到2019年”两种版本的结果,看period效应是否被异常年份带偏。

5. 模型选型与长期跑数据的几条建议

5.1 性别怎么处理:建议分性别建模

GBD数据里男女的疾病负担模式差异很大,比如甲状腺癌、乳腺癌、肺癌的年龄趋势完全不同,合并建模会把两性效应平均掉,画出来的年龄效应曲线谁都不像。我通常的做法是,先跑一个合并模型看整体,再按性别分两个模型跑,分别出预测曲线。这样做的代价是多跑几次,但结果解释起来清晰得多。

5.2 预测期长与DIC模型比较

npredict取多少是个经典问题。太短没意义,太长不可靠。我在实际项目里的经验是,15到20年是一个比较舒服的区间,既满足中长期规划的参考需求,又不会让不确定性区间宽到失去参考价值。如果你只是想做一个短期预警,也可以取5年。

模型选择上,用DIC比较APC、AP、AC三者的拟合与复杂度平衡。比如队列效应不明显时,DIC会倾向于AP模型,这时强上APC反而会让cohort效应的方差被随机游走先验压得太小,直观表现就是cohort曲线被拉成一条直线。这种信息模型自己会告诉你,不需要靠肉眼硬猜。

5.3 把预测值导出来做精细化图表

BAPC的默认绘图是base R风格,适合快速检查,但要放进论文或汇报材料里通常需要重绘。BAPC对象里保存了后验预测分布,可以把它提取成数据框后用ggplot2自定义图形。

我常用的做法是,把历史观测值和预测值合并成一个长表,标注“historic”和“projected”标签,然后按性别分面画折线图,再用geom_ribbon画置信区间。这样出来的图不仅好看,也更容易让不熟悉统计模型的合作者一眼看懂趋势走向。

再分享一个我自己的小习惯:跑模型前先把数据按年份、年龄组两个维度各画一张热图或堆叠图,花五分钟肉眼检查一下数据里有没有明显的空洞或跳跃。这个习惯帮我避免了至少三次因为数据筛选错误导致的结果返工,比任何模型诊断都管用。

GBD数据库加BAPC这套组合,真正跑顺以后,做疾病负担的年龄-时期-队列分解和未来趋势预测都会变得非常高效。关键在于把它当成一个“数据工程 + 模型调用”的流程来对待,耐心处理好前置的年龄组对齐和长宽转换,剩下的交给包本身就好。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询