You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为SAS数据集创建同ID6个月内手术史标识列?

问题说明

现有SAS数据集结构如下:

ID       Visit_Date        VISIT TYPE

001       JAN032000         OFFICE        
001       DEC141999         SURGERY       
001       FEB082002         OFFICE        
002       JUN272000         OFFICE        
002       APR142003         OFFICE        
003       MAR292000         SURGERY       
004       DEC072001         SURGERY       
004       FEB142002         OFFICE        

需求为新增列SX_6MO_B4_VISIT,规则:

  • 门诊(OFFICE)记录:标记1/0,1表示该患者本次门诊前6个月内有手术(SURGERY)记录,0表示无
  • 手术(SURGERY)记录:该列填充NA

用户尝试的PROC SQL代码报错“无法找到DATEDIFF函数”,代码如下:

PROC SQL;
SELECT *,
CASE WHEN EXISTS
(SELECT 1 FROM DATA D2 
WHERE D2.ID=D.ID AND
D2.VISIT_TYPE= "SURGERY" AND
AND D.VISIT_TYPE = "OFFICE" AND 
DATEDIFF(MM,D2.VISIT_DATE D.VISIT_DATE) <=6 )
THEN 1 ELSE 0 END AS SX_6MO_B4_VISIT
FROM DATA D;
QUIT;
错误原因
  1. DATEDIFF是SQL Server等其他SQL方言的函数,SAS PROC SQL不支持该函数,需使用SAS原生日期函数替代
  2. 代码存在语法错误:多了一个冗余的AND,且DATEDIFF的参数缺少逗号分隔
解决方案

方法1:修正后的PROC SQL实现

先将字符型日期转换为SAS日期值,使用INTNX函数计算日期边界,再通过自连接判断手术记录是否存在:

PROC SQL;
CREATE TABLE WANT AS
SELECT 
    ID,
    Visit_Date,
    `VISIT TYPE`,
    CASE 
        WHEN `VISIT TYPE` = 'SURGERY' THEN . /* SAS数值型缺失值,后续可格式化为NA */
        WHEN EXISTS (
            SELECT 1 
            FROM DATA D2 
            WHERE D2.ID = D.ID 
              AND D2.`VISIT TYPE` = 'SURGERY' 
              /* 手术日期在当前门诊日期前6个月范围内 */
              AND INPUT(D2.Visit_Date, DATE9.) >= INTNX('month', INPUT(D.Visit_Date, DATE9.), -6, 'same')
              AND INPUT(D2.Visit_Date, DATE9.) < INPUT(D.Visit_Date, DATE9.)
        ) THEN 1 
        ELSE 0 
    END AS SX_6MO_B4_VISIT
FROM DATA D;
QUIT;

/* 可选:将缺失值格式化为显示NA */
PROC FORMAT;
    VALUE NA_FMT . = 'NA';
RUN;

DATA WANT_DISPLAY;
    SET WANT;
    FORMAT SX_6MO_B4_VISIT NA_FMT.;
RUN;
  • INPUT(Visit_Date, DATE9.):将字符型日期(如JAN032000)转换为SAS可识别的日期值
  • INTNX('month', 日期, -6, 'same'):将当前门诊日期往前推6个月,保持日部分一致,得到时间范围的左边界
  • 手术日期需满足大于等于左边界且小于当前门诊日期,确保是门诊前6个月内的记录

方法2:DATA步实现(大数据集更高效)

通过排序+RETAIN保留最近手术日期,避免自连接,性能更优:

/* 按ID和日期升序排序 */
PROC SORT DATA=DATA OUT=SORTED_DATA;
    BY ID INPUT(Visit_Date, DATE9.);
RUN;

DATA WANT;
    SET SORTED_DATA;
    BY ID;
    RETAIN LAST_SX_DATE; /* 保留当前ID的最近手术日期 */
    SAS_Visit_Date = INPUT(Visit_Date, DATE9.); /* 转换为SAS日期 */
    
    /* 每个ID的第一条记录重置最近手术日期 */
    IF FIRST.ID THEN LAST_SX_DATE = .;
    
    /* 更新最近手术日期 */
    IF `VISIT TYPE` = 'SURGERY' THEN LAST_SX_DATE = SAS_Visit_Date;
    
    /* 生成目标列 */
    IF `VISIT TYPE` = 'SURGERY' THEN SX_6MO_B4_VISIT = .;
    ELSE DO;
        IF NOT MISSING(LAST_SX_DATE) AND LAST_SX_DATE >= INTNX('month', SAS_Visit_Date, -6, 'same') AND LAST_SX_DATE < SAS_Visit_Date THEN
            SX_6MO_B4_VISIT = 1;
        ELSE
            SX_6MO_B4_VISIT = 0;
    END;
    
    DROP SAS_Visit_Date LAST_SX_DATE; /* 删除临时变量 */
RUN;

/* 可选:格式化缺失值为NA */
PROC FORMAT;
    VALUE NA_FMT . = 'NA';
RUN;

DATA WANT_DISPLAY;
    SET WANT;
    FORMAT SX_6MO_B4_VISIT NA_FMT.;
RUN;

内容的提问来源于stack exchange,提问作者alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 12:45:07