SEER数据库2025版数据选择全攻略:从筛选条件到生存分析

发布时间:2026/10/11 21:54:57
SEER数据库2025版数据选择全攻略:从筛选条件到生存分析
9篇6章6节SEER 数据库的2025年数据集中的数据选择2026年版如果你正在用 SEER 数据库做肿瘤领域的回顾性研究那么这一节内容会直接关系到你后续统计结果的可靠性。这是本系列教程的第9篇对应第6章的第6小节主题是“2025年数据集中的数据选择”。简单说就是从SEER官方发布的2025版数据里把符合你研究定义的病例子集精准地挑出来——这个环节看起来只是在软件里点几下筛选项但实际操作中字段口径选错、诊断年份边界算错、类目合并不当都会让最终样本量和生存分析结果完全变样。我见过太多人把大量时间花在后期建模上结果前期数据选择出了问题返工成本相当高。这一篇我就按2025年数据集对应官方2025年内发布、包含更新随访信息的数据版本的实际界面和操作逻辑把数据选择的完整链路讲清楚包括Session类型怎么选、Selection条件怎么写、字段口径怎么核对以及我这些年踩过的坑和排查经验。1. 在动手筛选之前先把2025年数据的家底摸清楚1.1 版本结构比你想的更影响选择结果SEER数据每年更新一次2025版数据最直观的变化是纳入了更新年份的诊断病例和更长的随访周期。但这并不代表你直接选“最新一年”就万事大吉因为数据库内部是分文件、分登记中心、分队列组织的加载到SEER*Stat之后左侧列表里的数据文件名称、发布日期、随访截止点每一项都决定了你能筛出什么样本。实际操作经验是先看数据集名称里的提交版本标识。比如你看到的是以“Nov 2025”这类提交日期命名的文件它对应的通常是截至2024年底的随访数据并且把2024年诊断的病例纳入了新发病例范围。如果你做生存分析一定要搞清楚随访截止时间因为某个癌种如果晚近几年的病例随访时间太短直接纳入反而会造成删失比例过高。我在做某消化道肿瘤项目时最初把诊断年份区间设成2015到2024结果2023和2024年的病例中位随访时间不到一年删失率接近九成后续Cox回归的稳健性明显变差。后来我习惯在数据选择阶段就顺手统计一下每个诊断年份的生存月数分布再决定是否收口年份区间。另一个容易忽略的点是SEER官方发布的数据文件和字典是分开的。你在初始安装时选择加载哪些数据文件比如“Incidence”数据库、特定登记中心数据库、或者是带有治疗字段的附加数据库不同的组合会导致可用字段列表不同。如果某个字段在你当前加载的数据集中根本不存在Selection里自然就选不到这不是软件出了问题而是数据集没装全。1.2 为什么“数据选择”不是随便勾几个字段很多人把数据选择理解为“把变量拖出来筛一下”但SEER*Stat里的“选择”是一个有逻辑层次的流程先确定分析单位病例、人年还是事件再定义病例纳入标准最后决定输出哪些变量。每一步都会影响后续的数据结构和分析口径。比如同样一个问题“某癌种患者的生存分析”如果分析单位是“患者”你就要考虑多原发肿瘤的处理——同一个患者可能有多条记录每条记录对应一个原发肿瘤。数据选择时如果不限定首发肿瘤标志同一个人的多个原发灶会被当成多条独立记录你的样本量虚高生存时间也会被错误重复计算。反过来如果研究暴露因素是“是否接受手术”那治疗字段的缺失值、未知值该怎么归类也会直接影响分组结果。这些都不是简单勾选能解决的需要你在动手前就明确研究设计里的分析单位定义。我在教程里一直强调一个习惯把数据选择规则写成一份“课题筛选定义表”里面写清楚纳入标准、排除标准、每个标准对应的SEER字段名和取值口径。这个表既是你自己操作的备忘录也是后续写论文方法部分的重要素材。审稿人如果问“你的纳入标准为什么是这几条”你至少能拿出字段级的解释。2. SEER*Stat 的Session入口选择决定你后面怎么干活2.1 四种Session模式怎么选SEER*Stat打开后第一件事不是急着加载数据而是选择Session类型。常见的有Matrix、Rate、Frequency、Case Listing等。数据选择这一步绝大多数情况下用的是Case Listing Session因为它能让你按照病例级的筛选条件拿到明细数据并且可以导出成文本文件供后续R或Python分析。Rate Session更适合计算年龄调整发病率或死亡率它直接输出的是率值不是个案记录。如果你只是想知道“某癌种大概有多少例”用Frequency Session就够了它能快速输出频数表比Case Listing更轻量。但如果你要做倾向性评分匹配、列线图、机器学习模型你需要的是个案级的完整协变量信息这时候Case Listing才是正路。我见过有人在Rate Session里折腾半天想导出个案数据最后发现根本导不出来白白浪费时间。选择Session之后界面会要求加载数据文件。这里要注意每次打开Case Listing Session时要重新选择数据集文件软件不会自动记住你上次加载的是哪个。加载完成后界面上会出现三个主要选项卡Selection、Table、Output。我们下面把这三个部分逐个说透。2.2 判定标准什么样的研究任务适合哪种SessionRate Session目标是发病率/死亡率、Joinpoint趋势分析输出的是率和可信区间。Frequency Session目标是快速了解各分类变量下的事件数比如“按性别、种族分层的病例数”。Case Listing Session目标是获取病例级数据用于构建列线图、生存分析模型、以及任何需要逐条记录的分析。Survival Session直接做Kaplan-Meier和Cox模型时其实可以用专门模块但仍需要预先完成病例选择。我的个人经验是哪怕最终要算发病率我也建议先做一次Case Listing导出病例数据自己核对一遍关键变量的数据质量再回到Rate Session去计算。因为Rate Session里的筛选条件有时候不够直观一旦某个条件设置和你的本意不一致最终率值会有系统性偏差而这个偏差在率值层面很难一眼看出来。3. Case Listing Session中的字段与筛选条件设置3.1 Selection选项卡把纳入条件用字段和取值表达出来进入Case Listing后Selection选项卡是数据选择的核心战场。它的交互方式不是让你写SQL而是通过一组一组的“字段—比较符—取值”来构建条件条件之间可以按AND或OR组合。不过为了后面讲清楚逻辑我可以用等效的伪SQL来表达你正在构建的条件。SELECT * FROM SEER_RESEARCH_Nov2025 WHERE (Site_recode_ICD_O_3_WHO_2008 Pancreas) AND (DX_year BETWEEN 2010 AND 2019) AND (Behavior_code_ICD_O_3 Malignant) AND (Age_recode_with_single_years 35) AND (Age_recode_with_single_years 85) AND (First_malignant_primary Yes) AND (SEER_cause_specific_death_classification IN (Dead (attributable to this cancer), Alive or dead of other cause))这段伪代码不是让你在软件里粘贴运行而是帮助理解筛选条件的逻辑。实际界面里你要在下拉列表中找到“Site recode ICD-O-3/WHO 2008”字段选择等于再从弹出窗口里勾选“Pancreas”这样才完成一个条件行。经验要点SEER*Stat的Selection条件是可以叠加的同样一个字段可以出现多次。比如年龄条件可以拆成“年龄大于等于35”和“年龄小于等于85”两行逻辑关系选AND。如果你不小心把AND选成了OR样本量会瞬间爆炸而且表面上看不出异常只有对比不同条件下的频数才会发现。3.2 Table与Output一个是看数一个是取数Table选项卡控制的是频数列联表的表现形式决定你看到的是矩阵行、列还是计数。Output选项卡才真正决定导出的数据文件里包含哪些变量。很多第一次用的人会在Table里折腾半天以为那是在设置导出变量实际上Output里每个勾选项才对应最终文本文件里的每一列。Output里我会按研究需要勾选以下变量诊断年份、原发部位、病理类型、行为学编码、分化程度、诊断时的年龄、性别、种族、SEER历史分期、TNM分期如果有、肿瘤大小、淋巴结检出数、随访月数、生存状态、死因特定分类、首发肿瘤标志、是否多原发。勾选的时候注意字段显示名可能因为数据字典版本不同而不同比如有的年份显示“SEER summary stage 2000”后来版本显示“SEER summary stage 2018”要根据你的研究队列诊断年份来选择对应的分期变量。还有一个实用技巧Output里你可以把“Patient ID”也勾上。这样你就保留了一列患者唯一标识方便后续处理多原发病例时做去重和关联。如果研究单位是“肿瘤灶”而不是“患者”那这项意义不大但一旦需要患者级分析没有这列标识你后续会很被动。3.3 一项真实研究场景下的数据选择配置示例用一个我最常碰到的场景做演示研究者想探究某种罕见消化系统肿瘤的生存预后因素计划收集2010到2019年确诊的原发性恶性肿瘤病例。第一步确定部位选择。SEER里有多种部位字段最常见的是“Site recode ICD-O-3/WHO 2008”这是一个经过重编码的统计用部位分类比原始的ICD-O-3解剖部位编码更适合做人群统计。如果直接使用原始的ICD-O-3编码很容易因为编码层级过细导致同类肿瘤散落在多个编码下样本量被切碎。第二步确定行为学编码。恶性肿瘤的行为学编码是3原位癌是2。如果你只关注浸润性癌必须加上行为学等于恶性的条件否则原位癌病例会混进来影响生存率和复发相关分析。这个条件看起来基础但出错率极高因为SEER数据里很多早期癌种都包含了大量原位癌病例。第三步年龄区间。研究目标人群若关注中老年发病设定最小年龄35岁和最大年龄85岁是一个常见做法但你要想清楚85岁以上患者的死因信息有时不够完整过度高龄也会给后续合并症调整带来困难。第四步首发肿瘤标志。如果你只纳入首发恶性肿瘤就可以避免多原发记录带来的重复计算。但这里有个隐含代价某些癌种中多原发占比不低排除后会减少样本量。到底排除还是保留取决于研究问题的定义。做预后生存分析时我通常保留首发肿瘤标志等于Yes的病例因为后续死亡归因更干净。第五步随访时间和生存状态。Case Listing导出的数据里“生存月数”单位是完整月不是天数。字段“Vital status recode”通常是Alive或Dead的二分变量。更关键的是“SEER cause-specific death classification”它把死亡原因分为死于本癌种、死于其他癌种、死于其他原因、未知等类目。做肿瘤特异性生存分析时这个字段是你计算终点事件的核心必须在选择数据时保留并在后续分析中正确映射。配置完成后点ExecuteSEER*Stat会跑出一个频数Summary然后生成一个case listing表。这时别急着导出先扫一眼Summary里面的总病例数和你之前预估的范围做对比。如果差异超过预期优先检查条件行里的OR/AND逻辑。4. 筛选条件设置里的关键细节与避坑经验4.1 编码口径别混着用SEER数据库的字段经历了多次改版不同年份的诊断数据对应不同的编码体系。比如TNM分期早期诊断数据用的是AJCC 3rd edition或6th edition近些年则是7th和8th并存。数据选择阶段如果只勾一个“TNM stage”软件默认可能只返回某些年份的存在值其他年份全是空白。这时候你需要在选择条件里同时兼容多个TNM版本字段或者在后续分析里建立跨版本的分期映射规则。另一个典型问题是种族和民族的编码口径。美国SEER数据里的“Race recode”和“Origin recode”是两回事前者是种族大类后者是西语裔起源标识。如果你研究要比较不同族裔的生存差异必须同时选择这两个字段而不是只看其中一个。我的建议是在正式筛选之前先花二十分钟读一下该版本数据集的自变量字典重点关注你计划使用的那些字段的可用范围和缺失规则。不要依赖上一年的经验因为SEER每年都会有不少字段定义微调。我在2025版数据上就发现某些治疗相关字段的“未知/未记录”类目比例比往年有变化如果不更新认识很容易把未知类目误当成未治疗组。4.2 排除条件的反向设计数据选择的常见思路是正向列出纳入条件但更精细的做法是同时设计排除条件。比如排除确诊方式仅靠死亡证明或尸检的病例。这类病例没有完整的临床病程信息生存时间实际为0或缺失纳入分析会对生存曲线造成严重偏倚。排除生存月数为0且死因为本癌种的病例。这类病例通常在诊断当月死亡到底算生存0个月还是1个月如果不做处理Kaplan-Meier估计在0时刻就会产生不自然的骤降。排除关键协变量缺失的病例。但这里要谨慎不要一刀切全部剔除因为缺失本身可能有临床意义。比如分期未知可能是某个亚组患者没有接受完整检查直接剔除会导致选择偏倚。反向设计的价值在于它能让你在论文方法部分把“排除标准”写得一清二楚。我每次做完数据选择都会把正向纳入和反向排除分开记录这样后续同行评审时非常有底气。4.3 时间窗与随访足月性生存分析里最容易被低估的是“随访足月性”问题。SEER里的生存月数是按完整月计的所以确诊当月和次月之间的差异并不像真实天数那样精确。数据选择阶段你可以通过设置诊断年份的上限来避免纳入“随访不足的人群”。我一般会在方法里写明“为保证至少X个月的潜在随访诊断年份截止到某一年”。这个X值怎么定取决于研究的主要终点事件发生速度。如果癌种非常致命比如胰腺癌中位生存期只有几个月那哪怕只有一年随访也有意义。如果癌种预后良好比如甲状腺癌十年随访都未必能积累足够事件数你反而要尽量往前追溯诊断年份。这种时间窗选择没有统一公式但你必须在数据选择前做一次事件率预估而不是跟随默认的年份范围。5. 数据选择过程中的常见问题与排查技巧5.1 筛选后样本量为零或异常偏小这种情况最常发生在三个环节字段选择错误、取值列表理解偏差、条件逻辑用了AND但本意是OR。排查方法很简单在Selection里逐条移除条件每次移除后清点一次频数。比如你先只保留部位条件看有多少例再叠加行为学条件看剩下多少。这样几步做下来哪一层条件把样本量压到零就一目了然。如果是部位字段选错比如选了“Pancreas”却用的是原发灶数量字段可能出现大量0值如果是行为学编码取值选错比如在“Behavior code”里选了“In situ”而不是“Malignant”那恶性肿瘤病例会被整体排除。我的习惯是先用Frequency Session快速复算一遍候选条件组合下的频数如果结果和Case Listing一致再回到Case Listing里继续操作。这种交叉验证看起来多了一步但在样本量关乎课题成败的项目里值得花这五分钟。5.2 导出数据里出现大量空白字段空白不代表没有值有可能是字段名冲突。举个例子你在Output里勾选了多个版本的TNM分期字段但诊断年份较老的病例本来就没有新版本分期于是那些老病例在新版TNM字段下就是空白。这种结构性缺失是正常的但你要在导出前就明确哪一个字段作为主分析变量。SEER*Stat在Case Listing导出时还会把未选择的变量留空很多人以为导出了全部数据发现好多列是空的才意识到Output里的勾选才是导出的全部内容。所以导出前务必点开文件预览确认一遍列名不要直接拿去做分析。另外输出文件如果超过一定行数SEER*Stat默认可能会截断。你需要在导出选项里把最大行数上限调高或者选择不设上限。我早年曾因为没注意这个默认限制分析的时候总觉得样本量少了反复回去数数最后发现是导出被截断了。这个问题不小一旦你在下游分析中无意丢了一部分病例偏倚就埋下了。5.3 同一个患者的多个记录怎么处理数据选择的结果大概率包含同一个患者的多条记录原因是患者在不同时间被诊断出多个原发肿瘤。如果你做的是“以患者为单位”的研究就得在数据选择阶段确定保留策略。常见的做法是保留每个患者的首发恶性肿瘤记录或保留确诊日期最早的一条记录。但如果你研究的就是“第二原发癌”的预后那反而要保留后续记录并利用“first malignant primary indicator”字段筛选出符合条件的那些记录。处理多原发记录时患者ID、诊断序号、首发肿瘤标志这三个字段要同时导出缺一个都很难在外部准确完成去重。5.4 病例数可复现性问题科研项目的另外一大原则是结果可复现。SEER*Stat在每次执行操作时其实可以保存执行日志。我建议在完成数据选择后把Selection里的所有条件截图或复制保存连同执行时间、数据集版本、软件版本一起归档。这样以后哪怕换了一台电脑重新做也能完全复现当时的样本。这个问题听着简单但不少合作项目里因为某个人改了一下条件没记录最后两个人跑出来的样本量对不上浪费了几天时间排查。现在我会把数据选择流程录成一份Markdown记录每个条件都写清楚选择界面里的字段名和取值含义不写模糊的“某癌肿条件”这种习惯值得推荐。6. 拿到干净子集之后还有哪些必做的数据整理6.1 从数据选择到生存分析的数据格式转换Case Listing导出的是一个扁平文件一行是一条肿瘤记录。做经典生存分析前至少需要以下整理步骤把生存月数转成可用于建模的数值变量把生存状态和死因分类组合成事件指示变量把诊断年份、年龄转成数值或分组把分期、分化、手术等分类变量做因子化处理。事件指示变量的定义尤其重要。如果做总生存期OS事件定义为全因死亡如果做肿瘤特异性生存期CSS事件定义为死于本癌种。这里要特别小心“SEER cause-specific death classification”的映射SEER里有一类是“Dead due to this cancer”还有一类是“Dead due to other causes”映射过程中如果漏掉“Alive”作为删失你的事件数会虚高生存曲线会异常。数据选择阶段就要顺手把这些映射规则写出来不要等到建模阶段再临时定义。我通常在导出前就多勾一个字段“SEER other cause of death classification”它和死因特定分类互为补充能帮助区分其他死因的具体情况对竞争风险模型尤其有用。6.2 数据质量自查清单导出数据后先跑一遍下面的清单再进入建模总病例数是否和SEER*Stat Summary中的总数一致。每个关键变量的缺失值比例是否与数据字典预期相符。诊断年份分布是否和你的时间窗设定一致有没有出现奇怪的边界年份。生存月数最大值是否大于你的随访截止点有则说明队列里混入了不该有的记录。死亡事件数和死因分类各档位的合计是否等于生存状态字段的各档位合计。如果做了首发肿瘤筛选确认每个患者ID只出现一次。这套清单是我每次做SEER数据选择后必跑的例行程序能拦截掉绝大多数低级错误省下的时间远多于跑这些检查消耗的时间。6.3 把数据选择规则变成研究方法的一部分最后多说一句数据选择规则不是私下操作而是研究方法的组成部分。现在很多期刊要求论文里写明数据来源版本、下载日期、筛选流程图。你在数据选择阶段记录的每一条条件和排除标准最终都会变成论文中的一个流程框图或一段方法学描述。做这些记录时字段名尽量与SEER*Stat界面显示名保持一致取值可以统一为数字代码或文字标签但要在方法部分明确说明映射关系。审稿人通常会特别关注诊断年份范围、死因定义、多原发肿瘤处理这三块内容如果你能在数据选择阶段就整理清楚后续写文章的压力会小很多。根据我这个系列一贯的做法下一节会接着讲如何用导出的数据在R里计算标准化发病率并比较不同年份分段的趋势。如果你正好卡在数据选择这一步建议你把我上面提到的筛选定义表先做出来然后再点Execute导出效率和准确性都会有明显提升。