简介:这份资源是SaTScan软件的中文说明书,面向流行病学、公共卫生、地理信息及相关统计领域的研究者与数据分析人员,帮助解决空间、时间及时空数据中疾病集群检测与异常值识别的操作与理解问题。SaTScan作为一款自由软件,可执行地理疾病监测、时空扫描统计、前瞻性实时监测等任务,并支持离散与连续扫描数据、泊松模型、伯努利模型、时空置换模型、多项式模型、序模型、指数模型及空间变化时间趋势模型等多种方法,也适用于考古、天文、犯罪、生态、经济等领域的类似分析。资源包为doc格式,共1个文件,大小约485KB,内容涵盖软件目的、数据类型与方法、开发商与资助信息、下载安装指引,以及新墨西哥脑肿瘤、亨伯赛德儿童白血病、纽约市发热急诊、马里兰教育水平、人工生存数据等多个示例数据集与参数文件说明,便于读者对照理解模型配置与结果解读。目前已有2797人学习下载,适合需要系统查阅SaTScan中文操作与统计模型细节的初、中级用户参考。
1. 从一份中文说明书说起:SaTScan 到底能帮你做什么
如果你手头有一批带经纬度的病例数据,领导问你“这几个街道的发病率是不是异常偏高”,你大概率会打开 R 或者 Python 写一堆代码,然后卡在“这个 P 值到底怎么算才严谨”上。SaTScan 就是干这个的——它把空间扫描统计、时空扫描统计和纯粹时间扫描统计打包成一个带界面的工具,你只需要准备好病例文件、人口文件和坐标文件,它就能告诉你:研究区域内是否存在统计学显著的聚集,以及这个聚集覆盖哪些位置、持续多长时间。这份中文说明书的价值在于,它把原本散落在英文文档、论文和邮件列表里的操作逻辑,压缩成一份能直接对着操作的参考。适合公共卫生监测、流行病学分析、生态学空间格局研究,以及任何需要判断“事件在空间或时间上是否随机分布”的从业者。你不需要是统计学家,但需要知道你的数据属于哪种模型。
2. 先搞懂模型再动手:七种扫描统计的选型逻辑
2.1 离散 vs 连续:你的位置是固定的还是随机的
SaTScan 把所有扫描统计分成两大阵营:离散扫描和连续扫描。离散扫描假设观测位置是固定的、非随机的,比如县、普查区、邮政编码区、学校、医院,这些位置在研究期间不会移动。你手里如果有每个县的病例数和人口数,那就是典型的离散扫描场景。连续扫描则假设观测位置本身是随机的,可能出现在研究区域内的任何地方,比如森林里鸟巢的坐标、犯罪现场的位置点。连续扫描目前只支持连续泊松模型,研究区域由用户定义,可以是矩形、多边形或一组凸多边形的集合。
选型的第一步就是问自己:我的分析单元是固定的地理边界,还是随机分布的点?如果是前者,继续往下看离散模型;如果是后者,直接跳到连续泊松模型。这一步搞错,后面所有参数都是白搭。
2.2 离散模型七兄弟:从泊松到空间变化时间趋势
离散扫描统计下,SaTScan 提供了七种概率模型,每种对应不同的数据类型和假设。我把它们整理成一张表,方便你对着自己的数据直接匹配:
| 模型 | 数据类型 | 典型场景 | 需要的人口/控制信息 |
|---|---|---|---|
| 离散泊松 | 病例数 + 人口数 | 县級中风发病、癌症登记 | 人口文件,按地点和时间 |
| 伯努利 | 0/1 事件 | 出生缺陷 vs 正常新生儿 | 病例文件 + 控制文件 |
| 时空置换 | 仅病例,无人口 | 急诊科发热就诊、救护车派遣 | 不需要人口或控制 |
| 多项式 | 多类别计数 | 脑膜炎不同克隆群 | 每个类别的病例位置 |
| 序模型 | 有序分类 | 乳腺癌早/中/晚期 | 每个类别的病例位置 |
| 指数 | 生存时间 + 删失 | 前列腺癌诊断到死亡时间 | 诊断时间 + 生存/删失时间 |
| 正态 | 连续值 | 出生体重、体重增加 | 每个观测的连续属性 |
| 空间变化时间趋势 | 病例 + 人口 + 时间 | 寻找异常高/低的时间趋势 | 人口文件,按地点和时间 |
这张表不是让你背的,是让你在打开 SaTScan 之前先确认:我的数据里有病例数吗?有人口数吗?有控制组吗?有生存时间吗?有连续测量值吗?每个问题对应一个模型。选错模型的后果不是报错,而是结果完全不可解释——比如你拿伯努利模型去跑只有病例没有控制的数据,软件会直接拒绝;你拿时空置换模型去跑跨越五年的数据,P 值可能因为人口变化而产生偏差。
2.3 时空置换模型的特殊约束:为什么它没有纯粹空间版本
时空置换模型是唯一一个不需要人口或控制信息的模型,它只要求每个病例有空间位置和时间。它的零假设是:病例在空间和时间上的分布是独立的,不存在时空交互。换句话说,如果某个地区在某段时间内病例数偏高,但同期所有地区都偏高,那不算聚集;只有当这个地区比其他地区在该时间段内显著偏高,才算时空聚集。
这个模型自动调整纯粹空间和纯粹时间的聚集,所以它没有单独的空间版本或时间版本。但这里有一个血泪经验:如果你的研究期间超过一年,而且不同地区的人口增长速度差异很大,时空置换模型可能会产生有偏的 P 值。原因很简单——人口增长快的地区,病例数自然增加,但模型没有人口数据来校正这一点,它会误以为这是疾病风险升高。说明书里明确建议:研究期间超过几年时,慎用时空置换模型,除非你能确认整个研究区域的人口增减是均匀的。
2.4 泊松模型的人口插值:普查年之间怎么算
离散泊松模型是公共卫生领域最常用的模型,因为它只需要病例数和人口数。但这里有一个容易被忽略的细节:人口数据通常只在普查年份提供,比如 1973、1982、1991,而你的研究期间可能是 1973 到 1991 之间的每一年。SaTScan 的处理方式是线性插值——在两个普查年之间,人口数按线性变化计算;在第一个普查年之前,人口数等于第一个普查年的值;在最后一个普查年之后,人口数等于最后一个普查年的值。
这意味着,如果你的人口数据只有两个普查年,中间年份的人口数是估算出来的。对于人口变化剧烈的地区,这种估算可能引入误差。我一般会尽量提供更多年份的人口数据,哪怕是从年度统计年鉴里摘出来的,也比只有普查年强。说明书里的新墨西哥脑肿瘤数据集就是一个浓缩版,只用了 1973、1982、1991 三个年份的人口,完整版有每年的人口和种族变量。
3. 从零跑通第一个分析:文件格式、参数设置与结果解读
3.1 三类输入文件的格式规范
SaTScan 的输入文件是纯文本格式,扩展名分别是 .cas(病例文件)、.pop(人口文件)、.geo(坐标文件),伯努利模型还需要 .ctl(控制文件)。每个文件的列顺序和含义是固定的,不能随意调换。以离散泊松模型为例:
病例文件(.cas)的格式是:<位置ID> <病例数> <时间> <协变量...>。位置ID 可以是县名、邮政编码或任意唯一标识;病例数是该位置在该时间的病例数量;时间可以是年、月、日,取决于你的研究期间精度。
人口文件(.pop)的格式是:<位置ID> <时间> <人口数> <协变量...>。注意人口文件的时间列必须与病例文件的时间列对应,否则软件无法匹配。
坐标文件(.geo)的格式是:<位置ID> <X坐标> <Y坐标>。X 和 Y 可以是经纬度,也可以是直角坐标,但必须在参数设置里声明坐标系类型。
下面是一个最小化的离散泊松模型输入示例:
# 病例文件 nm.cas # 位置ID 病例数 年份 年龄组 性别 county1 5 1973 1 1 county1 3 1973 2 1 county2 8 1973 1 2 county2 2 1973 2 2 # 人口文件 nm.pop # 位置ID 年份 人口数 年龄组 性别 county1 1973 12000 1 1 county1 1973 11500 2 1 county2 1973 9800 1 2 county2 1973 10200 2 2 # 坐标文件 nm.geo # 位置ID X坐标 Y坐标 county1 100.5 35.2 county2 101.3 34.8逻辑说明:病例文件和人口文件通过“位置ID + 时间 + 协变量”联合匹配。协变量列是可选的,但如果你在参数里指定了协变量,两个文件都必须包含对应的列。坐标文件只按位置ID匹配,不需要时间列。参数说明:年龄组和性别是分类协变量,SaTScan 会自动按这些变量分层计算期望病例数。如果你不需要协变量调整,把这两列去掉即可,但两个文件必须同时去掉。
3.2 参数文件的核心设置项
SaTScan 的参数可以通过图形界面设置,也可以直接编辑参数文件(.prm)。图形界面适合新手,但参数文件更适合批量运行和版本控制。以下是一个典型的离散泊松时空扫描参数文件的关键片段:
# 参数文件示例:离散泊松时空扫描 Input Type = Case File Case File = nm.cas Population File = nm.pop Coordinates File = nm.geo Model Type = Discrete Poisson Scan Type = Space-Time Time Precision = Year Study Period = 1973 1991 Spatial Window Max = 50% Temporal Window Max = 50% Number of Replications = 999 Adjust for Covariates = Yes Covariates = AgeGroup Sex Output File = nm_results.txt逻辑说明:Scan Type决定是纯粹空间、纯粹时间还是时空扫描。Spatial Window Max是空间扫描窗口的最大比例,默认 50%,意思是聚集区域最多覆盖研究区域内 50% 的人口或病例。Temporal Window Max同理,控制时间窗口的最大长度。Number of Replications是蒙特卡洛模拟次数,999 是常用值,次数越多 P 值越稳定,但计算时间越长。Adjust for Covariates开启后,软件会按协变量分层计算期望值,适合有年龄、性别等混杂因素的数据。
参数说明:Time Precision必须与病例文件的时间格式一致,可以是 Year、Month、Day。Study Period是研究期间的起止时间,格式与 Time Precision 对应。Output File指定结果输出路径,结果文件包含每个聚集的位置、时间范围、病例数、期望病例数、相对风险和 P 值。
3.3 结果文件解读:相对风险与 P 值
SaTScan 的输出文件包含多个部分,最核心的是聚集列表。每个聚集包含以下关键字段:
- Location IDs:聚集覆盖的位置标识
- Time Frame:聚集的时间范围
- Number of Cases:聚集内的实际病例数
- Expected Cases:基于零假设的期望病例数
- Relative Risk:聚集内风险与聚集外风险的比值
- Log Likelihood Ratio:对数似然比,用于排序聚集
- P-Value:蒙特卡洛模拟得到的 P 值
相对风险大于 1 表示聚集内风险高于聚集外,小于 1 表示低于聚集外。P 值小于 0.05 通常被认为统计学显著,但要注意多重比较问题——SaTScan 在计算 P 值时已经考虑了扫描窗口的多重比较,所以不需要额外校正。我一般会按 Log Likelihood Ratio 从高到低排序,优先关注 P 值显著且相对风险高的聚集。
提示:如果输出文件里出现“No clusters found”,不要急着怀疑数据有问题。先检查参数设置里的扫描窗口是否太小,或者研究期间是否设置正确。有时候把 Spatial Window Max 从 10% 调到 50%,就能发现之前被忽略的聚集。
4. 避坑与排查:五个让新手翻车的典型场景
4.1 坐标文件用了经纬度但没声明坐标系
现象:软件运行后报错“Coordinates out of range”或结果明显不合理,聚集位置漂移到研究区域外。
原因:SaTScan 默认使用直角坐标,如果你直接填入经纬度(比如纬度 35.2,经度 100.5),软件会把它们当成平面坐标处理,导致距离计算错误。
解决:在参数设置里把 Coordinate Type 改为 Latitude/Longitude。注意经纬度格式下,X 列填经度,Y 列填纬度,顺序不能反。如果研究区域跨越多个纬度,建议改用投影坐标系,避免高纬度地区的距离畸变。
4.2 病例文件和人口文件的时间列不匹配
现象:软件提示“No cases found”或“Population file is empty”,但文件里明明有数据。
原因:病例文件的时间列是年份(如 1973),人口文件的时间列是日期(如 1973/01/01),或者一个是整数一个是字符串,导致匹配失败。
解决:确保两个文件的时间列格式完全一致。如果 Time Precision 设为 Year,两个文件的时间列都只写年份;如果设为 Day,都写完整日期。我一般会在 Excel 里先把两列格式统一,再导出为纯文本。
4.3 伯努利模型忘了提供控制文件
现象:选择伯努利模型后,软件无法运行,提示缺少控制文件。
原因:伯努利模型需要病例文件(.cas)和控制文件(.ctl),控制文件记录每个位置的控制组数量。很多人只准备了病例文件,以为和泊松模型一样只需要病例和人口。
解决:伯努利模型的控制文件格式是<位置ID> <控制数>,每个位置一行。如果你有多个时间点,控制文件也需要对应的时间列。控制组的选择要谨慎——比如出生缺陷研究里,控制组应该是同期无出生缺陷的新生儿,而不是所有儿童。
4.4 时空置换模型跑多年数据导致 P 值偏差
现象:用时空置换模型分析跨越五年的数据,发现了大量“显著”聚集,但换用泊松模型后这些聚集消失了。
原因:时空置换模型不校正人口变化。如果某些地区人口增长快,病例数自然增加,模型会误判为疾病风险升高。
解决:研究期间超过一年时,优先使用离散泊松模型,并提供逐年人口数据。如果只能用时空置换模型,尽量把研究期间缩短到一年以内,或者在结果解读时注明人口变化的潜在影响。
4.5 蒙特卡洛模拟次数太少导致 P 值不稳定
现象:同样的数据,两次运行得到不同的 P 值,有时显著有时不显著。
原因:Number of Replications 设置太低(比如 99),蒙特卡洛模拟的随机性导致 P 值波动。
解决:把 Number of Replications 提高到 999 或 9999。999 次模拟的 P 值标准误大约是 0.01,对于大多数应用足够;如果 P 值接近 0.05 边界,建议用 9999 次确认。计算时间会线性增加,但现在的机器跑 9999 次通常也在可接受范围内。
5. 进阶技巧:用序模型和指数模型处理非计数数据
5.1 序模型:当你的分类有高低之分
序模型和多项式模型都处理分类数据,但序模型要求类别之间有顺序关系。比如乳腺癌的早期、中期、晚期,或者教育水平的低、中、高。序模型可以搜索高值聚集(高类别病例过多)、低值聚集(低类别病例过多),或者同时搜索两种。如果你把类别顺序反过来,高值聚集和低值聚集的结果会对调。
实际操作中,序模型的输入文件格式是<位置ID> <类别> <时间>,每个病例一行。如果你有 1000 个病例,文件就有 1000 行。坐标文件和其他模型一样。参数设置里需要指定类别数量和搜索方向。我一般会先跑一次双向搜索,看看高值和低值聚集是否对称,再决定是否需要单向搜索。
5.2 指数模型:生存时间数据的两个时间变量
指数模型处理生存时间数据,但这里有一个容易混淆的点:数据里有两个时间变量。第一个是诊断时间,这是扫描窗口扫描的维度;第二个是生存时间(诊断到死亡或删失的时间),这是每个病例的属性,不参与扫描。模型关心的是:扫描窗口内是否包含异常多的小生存时间或大生存时间的病例。
输入文件格式是<位置ID> <诊断时间> <生存时间> <删失指示>。删失指示用 0/1 表示,1 表示删失(随访结束仍未发生事件),0 表示未删失(事件已发生)。参数设置里需要指定哪个是诊断时间、哪个是生存时间。指数模型的 P 值不依赖于生存时间服从指数分布,因为随机化是通过置换时空位置和生存时间属性完成的,所以即使真实生存时间分布不是指数,统计推断仍然有效。
5.3 连续泊松模型:随机点位的空间聚集检测
连续泊松模型是唯一一个连续扫描统计,适用于观测位置本身随机分布的场景。比如森林里鸟巢的坐标、犯罪现场的位置点。研究区域由用户定义,可以是矩形、多边形或凸多边形集合。输入文件只需要病例文件(每个观测一行,包含 X、Y 坐标)和研究区域定义文件。
参数设置里需要指定研究区域的边界。SaTScan 支持矩形和多边形两种定义方式。矩形用左下角和右上角坐标定义;多边形用顶点坐标序列定义,首尾顶点自动闭合。连续泊松模型的零假设是观测点服从均匀空间泊松过程,备择假设是存在强度高于背景的聚集区域。结果里的相对风险表示聚集内点密度与聚集外点密度的比值。
从那以后我每次拿到新数据,都会先画一张点位图,确认研究区域边界和坐标范围,再打开 SaTScan。这个习惯帮我省掉了至少三次因为坐标写反而导致的整夜重跑。希望帮到你。
本文还有配套的精品资源,点击获取