作为环境健康领域的研究者,我们常面对这样的现实:当某城市连续一周PM10浓度偏高后,呼吸系统疾病就诊量在随后几天逐渐上升——这种“污染当下不显,影响滞后显现”的现象,正是公共卫生研究的核心难题。
早在上世纪90年代,研究者就发现空气污染对健康的影响并非即时消散,而是存在滞后效应,且这种效应还可能随时间呈现非线性变化。
比如,低温对心血管疾病的影响可能在3天后达到峰值,而PM10的危害可能持续一周以上。
为解开这种复杂关系,分布式滞后非线性模型(DLNM)应运而生。它既能捕捉暴露因素(如PM10)与健康结局(如死亡)的非线性关联,又能刻画这种关联随时间的滞后模式,逐渐成为环境流行病学的“利器”。
全文将从工具准备讲起,带大家用R语言的dlnm包一步步实现模型构建,再通过多种可视化方法解读结果——从整体效应曲线到三维曲面图,让抽象的滞后效应变得直观。无论你是刚接触数据分析的学生,还是需要解决实际问题的研究者,都能从中找到可用的方法。
专题项目文件(报告代码PPT)已分享在交流社群,阅读原文进群和500+行业人士共同交流和成长。
一、环境准备:从工具安装到镜像选择
当我们想探究空气污染如何在 days 后影响健康时,首先得搭好“工作台”。R语言作为数据分析的强大工具,搭配RStudio的可视化界面,能让整个分析过程更顺畅。
1.1 R与RStudio的安装技巧
安装R时,直接从官网下载常因服务器在国外而速度缓慢。我们可以选择国内的清华镜像站(mirrors.tuna.tsinghua.edu.cn/CRAN/),不仅下载…
RStudio的安装更简单,直接用电脑自带的应用商店就行。安装完成后首次打开,它会让你选择关联的R版本,选刚装的64位版本就好。打开后,左边的console窗口就是我们写代码的地方,像个随时待命的助手。

Yangfei Chen
可下载资源
9.Python用RNN循环神经网络:LSTM长期记忆、GRU门循环单元、回归和ARIMA对COVID-19新冠疫情新增人数时间序列预测
二、核心工具与数据:包的导入与数据初探
有了工具,还得备好“材料”——分析用的包和数据。
2.1 关键包的安装与加载
分布式滞后非线性模型的核心包是dlnm,它能帮我们构建暴露因素与滞后时间的交叉关系。另外,处理时间序列需要tsModel包,拟合平滑曲线需要splines包。安装dlnm时,在console里输入安装命令,看到类似下图的提示,就说明安装成功了。

每次打开RStudio,都要加载这些包才能用它们的功能,就像用工具前先把它们从抽屉里拿出来:
每次打开RStudio,都要加载这些包才能用它们的功能,就像用工具前先把它们从抽屉里拿出来:
2.2 数据长什么样?
我们用的是某城市的空气污染与健康数据,包含日期、死亡数、PM10浓度、温度等信息。加载数据后,用head()函数看看前6行,能快速了解数据结构:
# 加载内置的某城市数据集
data(cityHealthData)
# 查看前6行数据
head(cityHealthData)

随时关注您喜欢的主题
结果里,date是日期,death是每日死亡数,pm10是可吸入颗粒物浓度,temp是温度。从数据能看出,PM10浓度有时会出现NA(缺失值),这在实际数据中很常见,后续分析得注意处理。
三、DLNM建模:如何捕捉“滞后”的影响?
假设我们想知道PM10浓度从当天到第7天(滞后0-7天)对死亡数的影响,DLNM能帮我们把这种“随时间变化的关联”刻画出来。
3.1 构建交叉基矩阵
交叉基矩阵是DLNM的核心,它能同时处理PM10的非线性效应和滞后效应。我们让PM10的暴露-反应关系为线性(fun = “lin”),滞后模式用3个自由度的自然样条(df = 3)描述:
# 创建PM10滞后0-7天的交叉基矩阵
cb_pm <- crossbasis(cityHealthData$pm10,
lag = 7,
argvar = list(fun = "lin"),
arglag = list(fun = "ns", df = 3))
3.2 拟合模型:控制“干扰因素”
死亡数还可能受温度、时间趋势影响(比如冬天死亡数通常更高),所以建模时得把这些“干扰因素”加进去。我们用准泊松回归(quasipoisson),因为死亡数是计数数据:
time_seq <- seq(nrow(cityHealthData))
# 拟合模型,控制温度和时间趋势
model <- glm(death ~ cb_pm + ns(temp, 3) + ns(time_seq, 8*14),
family = quasipoisson,
data = cityHealthData)
这里,ns(temp, 3)用3个自由度的样条函数处理温度的非线性影响,ns(time_seq, 8*14)则控制时间趋势(每年8个自由度,共14年)。
3.3 初步可视化:整体效应与等高线
模型建好后,我们可以预测不同PM10浓度下的相对风险(RR),并画图看看:
# 预测PM10浓度0-30μg/m³时的风险
pred <- crosspred(cb_pm, model, at = 0:30)
# 画整体效应图(累积滞后0-7天的总效应)
plot(pred, "overall", xlab = "PM10 (μg/m³)", ylab = "RR")
# 画等高线图(展示暴露水平和滞后时间的联合影响)
plot(pred, "contour", key.title = title("RR"))

整体效应图显示,随着PM10浓度升高,RR值上升,说明PM10浓度越高,死亡风险越大。

等高线图里,颜色越深表示RR越高,能看出在滞后2-3天左右,PM10的影响可能更明显。
四、多维度可视化:让滞后效应“看得见”
光看整体效应还不够,我们可以从更多角度解读,就像用不同镜头拍同一物体,看得更清楚。
4.1 三维曲面图:暴露、滞后与风险的“立体关系”
用plotly包画三维图,能直观看到PM10浓度、滞后时间和RR的关系:


从图中能发现,滞后3天时,PM10浓度升高带来的RR上升更显著,这比单纯看数字更直观。
4.2 切片图:固定一个变量看变化
- 固定滞后时间看暴露影响:比如比较滞后0天、3天、7天的暴露-反应曲线:

图中滞后3天的曲线斜率更大,说明此时PM10对死亡的影响更强。
- 固定暴露水平看滞后模式:比如看PM10浓度为10、20、30μg/m³时,滞后效应如何变化:

能看出浓度越高,滞后3天左右的RR峰值也越高。

4.3 累积效应曲线:总影响有多大?
把滞后0-7天的效应加起来,就是累积效应,能告诉我们PM10的总影响:

红色虚线以上的部分,说明PM10浓度升高会增加死亡风险。
五、数据导入进阶:怎么用好自己的CSV数据?
实际分析中,我们常需要用自己收集的数据(比如某城市的监测数据),这里分享两种导入CSV文件的方法。
5.1 用代码导入(适合有基础的用户)
用readr包的read_csv函数,能灵活处理中文和缺失值:
# 安装并加载readr包
install.packages("readr")
library(readr)
# 导入CSV文件
my_data <- read_csv(
"某城市数据.csv",
col_names = TRUE, # 第一行作为列名
na = c("", "NA", "无数据"), # 把空值、NA、无数据都视为缺失值
locale = locale(encoding = "UTF-8"), # 处理中文
skip = 1 # 跳过第一行(如果有多余标题)
)
5.2 用RStudio界面导入(适合初学者)
- 在RStudio右下角“Environment”面板点“Import Dataset”→“From Text (readr)…”
- 找到你的CSV文件,预览时检查:分隔符是不是逗号,首行是不是列名,编码选UTF-8(中文)
- 点“Import”,RStudio会自动生成代码,数据就导入成功了
结语
从工具准备到模型构建,再到用多种图表“拆解”滞后效应,我们一步步揭开了空气污染对健康影响的“时间密码”。DLNM的价值,就在于它能帮我们看清那些“看不见的延迟影响”——这不仅对学术研究重要,对制定空气污染防控政策也同样关键。比如,当我们知道PM10的滞后3天影响最大,就可以在污染高峰后3天加强医疗资源调配,减少健康损失。
希望这篇文章能让你对分布式滞后非线性模型有更清晰的认识,下次处理类似数据时,不妨试试用这些方法,或许会有新的发现。
关于分析师
关于分析师
Yangfei Chen
在此对 Yangfei Chen 对本文所作的贡献表示诚挚感谢,她在武汉大学完成了通信工程专业的学习,专注深度学习与数据采集领域。擅长 Python、数据采集、深度学习。她在数据采集与深度学习应用方面拥有扎实的技术积累,尤其在利用 Python 进行数据获取与处理、构建深度学习模型解决实际问题等方面具备丰富经验,能够为相关项目提供专业的技术支持与分析思路。
每日分享最新报告和数据资料至会员群
关于会员群
- 会员群主要以数据研究、报告分享、数据工具讨论为主;
- 加入后免费阅读、下载相关数据内容,并同步海内外优质数据文档;
- 老用户可九折续费。
- 提供报告PDF代找服务
非常感谢您阅读本文,如需帮助请联系我们!