![]()
系列简介
这是我们一系列原创技术贴,从易到难,每天学习一点。所有内容均为疾控数据分析、科研论文相关,或者说很多和现在的热门监测预警相关,所以我们这个系列就叫“监测预警基础”。
之前很多老师反馈这种小专题的形式特别好,可以一口气彻底学透一种方法,好的,我们又来了!
这次是分布滞后非线性模型,我们初步计划用8小节左右的内容讲通它的前世今生,以及如何使用。所以我们这个小专题的名字就叫做《八小篇搞懂DLNM》
今天是第6小篇——开始R语言实操!
前面5篇我们把 DLNM 的原理、前置知识、应用场景全部讲透了。很多同行最期待的就是实操环节:道理都懂了,到底怎么用 R 把模型跑起来?
今天我们就从零开始,用模拟的疾控标准时间序列数据,带你走完从数据准备、预处理到模型拟合的完整流程。所有代码都附带逐行注释,复制粘贴就能直接运行,零基础也能跟着跑通第一个 DLNM 模型。
我们以日平均气温对传染病日发病数的影响为案例,这是疾控最经典的应用场景。全程基于泊松分布框架,和我们之前讲的 GLM/GAM 逻辑完全一致,学习门槛很低。
![]()
DLNM 的核心分析依赖dlnm包,它由 DLNM 方法的提出者 Gasparrini 团队开发,是目前最权威、最通用的实现工具。再搭配几个数据处理、样条分析的基础包即可。
运行以下代码完成安装与加载:
library(lubridate)![]()
DLNM 分析的是时间序列数据每一行代表一天,每一列是一个变量。疾控场景下最基础的数据结构,必须包含以下 4 类信息:
![]()
为了让大家不用找数据就能直接练习,我们先生成一份模拟的 3 年日数据,特征完全贴合真实疾控数据:温度有季节波动,发病数与温度呈 U 型关系,同时存在季节趋势与星期效应。
)下面让气温的影响分布在滞后 0~14 天,并假设滞后 5 天左右影响最强。
temp_lag <- as.numeric(temp_lag_mat %*% lag_weight)再生成每日发病数。这里假设气温与发病风险呈 U 型关系,20℃左右风险最低。
head(dat)运行完成后,用
head(dat)查看前 6 行,就能得到一份标准的分析数据集。和 GLM、GAM 一样,DLNM 也必须控制时间序列中的混杂因素,最核心的是长期趋势与季节波动星期效应。我们需要先生成对应的变量。
)变量作用解释:time:配合自然样条函数ns(),用来控制长期趋势和季节波动,这是时间序列研究的标准操作。我们通常设置每年 6~8 个自由度,3 年数据总自由度取 21 左右。dow:控制一周内的报告差异,比如周一报告数往往偏高,周末偏低。必须转为分类变量放入模型。
![]()
交叉基函数是 DLNM 的灵魂,对应我们第四篇讲的核心原理:同时在暴露维度和滞后维度构造样条基,再交叉组合。
dlnm包中用crossbasis()函数实现,这是整个分析最核心的一行代码。
)参数逐一说清
x = dat$temp:我们要研究的核心暴露因素,这里是日平均气温。lag = 14:设定最大滞后天数为 14 天,也就是我们认为温度的影响最多持续 14 天。这个值要根据疾病特征设定,传染病通常 7~14 天,死亡 / 慢病通常 14~21 天。argvar(暴露维度):fun = "ns":使用自然样条拟合暴露 - 反应关系,捕捉非线性;
df = 4:暴露维度设置 4 个自由度,既能拟合 U 型 / J 型曲线,又不会过度波动,是疾控研究的常用设置。
arglag(滞后维度):
fun = "ns":同样用自然样条对滞后效应进行平滑约束,解决相邻滞后天数的共线性问题;
df = 3:滞后维度通常自由度更低,保证滞后曲线平滑,3~4 个自由度是常规选择。
运行完这行代码,cb就是我们构造好的交叉基变量,接下来直接放进模型即可。
![]()
DLNM 本质上还是 GLM 框架,所以我们直接用基础的glm()函数拟合,和我们第二篇讲的泊松 GLM 语法几乎完全一样 ——唯一的区别,就是把普通的温度线性项,换成了我们刚构造好的交叉基cb
summary(model)我们把公式拆解开,和第二篇的 GLM 公式一一对应,你会发现逻辑完全一致:
cases ~:结局变量是日发病数,对应公式里的病例数。cb:交叉基项,是模型的核心,替代了原来的单一温度变量,对应公式里的cb第二项ns(time, df = 7*3):时间的自然样条,每年 7 个自由度,3 年共 21 个,用来控制长期趋势和季节波动factor(dow):星期效应分类变量,控制每周内的报告波动family = poisson(link = "log"):指定泊松分布、对数联系函数,和标准泊松 GLM 完全一致
运行summary(model)后,你会看到一长串系数 —— 这些就是交叉基各个基变量对应的系数。但不用慌,我们不需要手动解读这些系数,后续用专门的函数就能提取出我们关心的相对危险度、置信区间。
![]()
模型跑通了,我们先提取一个最直观的结果:整个 14 天滞后期内的累积效应。比如我们以 20℃为参照,看看 28℃的累积发病风险是多少。
用crosspred()函数进行预测:
)例如,提取 28℃相对于 20℃的 14 天累积 RR:
)如果输出结果为:
28.0 1.25 1.10 1.42可以解释为:与 20℃相比,28℃暴露后 14 天内的累积发病风险升高 25%,且差异有统计学意义。如果 95%CI 跨过 1,例如 0.95~1.30,则不能认为差异有统计学意义。
![]()
1. 三维图:看“气温—滞后—发病风险”的整体形状
)三维图中,横轴是气温,纵轴是滞后天数,竖轴是 RR。曲面越高,说明该气温在对应滞后天的发病风险越高。
2. 等高线图:定位高风险组合
)3. 累积效应图:看 14 天总风险
abline(v = 20, lty = 3, col = "grey60")实际分析时,只需要把模拟数据替换成自己的监测数据,保证至少包含以下 4 列:
日期 发病数 日平均气温 日降水量到这里,你就完成了一个完整的 DLNM 实操流程:数据准备、交叉基构建、模型拟合、RR 提取,以及三维图、等高线图和累积效应图绘制。
![]()
![]()
编辑:普通疾控人 | 审核:诗酒趁年华
文章来源 | 原创
说明 | 转载只为分享,如有侵权联系删除
©版权声明 | 部分信息和图片来自公开网络
转载请注明
再次转载请注明出处
![]()
科普健康 | 宣传疾控
本号为多位疾控机构从业者运营
重点关注国内外健康事件
致力于疾控科普
在做好科普服务大众的同时
做好疾控机构的宣传
让更多的人了解疾控,拥抱健康
欢迎加「小编」微信(cdcjkr126com)
本文具体说明
本文为原创内容,文章为个人理解所学,不涉及疫情信息及内部保密数据,发表的目的为自我总结及给有需求的人士学习使用。如有不妥之处,欢迎联系小编修改、删除。
更多精彩视频,尽在“CDC疾控人”视频号
![]()
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.