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

如何在SAS中高效按指定时间点汇总各组事件发生数?

问题描述

需要生成如下格式的表格,汇总截至指定时间点的事件发生数量:

Timepoint  GroupA  GroupB
le 30        n       n
le 90        n       n
le 180       n       n
le 365       n       n

所用数据为包含group、tte和event(1表示发生事件)的时间事件数据,示例如下:

group  tte  event
A      20    0
B      40    0
A      60    1
B      80    0
A      100   1
B      120   1

目前通过多次调用proc freq逐一生成结果,代码如下:

proc freq data = have;
    tables event * group/ nopercent nocol norow;
    where tte le 30 and event eq 1;
run;

proc freq data = have;
    tables event * group/ nopercent nocol norow;
    where tte le 60 and event eq 1;
run;

请问是否有更高效的实现方式?

高效实现方案

方案1:PROC SQL一次性生成所有时间点汇总

通过union all合并多个时间点的统计结果,只需一次数据扫描即可完成所有时间点的累计事件数计算:

proc sql;
    create table event_summary as
    select 
        'le 30' as Timepoint,
        sum(case when group='A' and tte <=30 and event=1 then 1 else 0 end) as GroupA,
        sum(case when group='B' and tte <=30 and event=1 then 1 else 0 end) as GroupB
    from have
    union all
    select 
        'le 90' as Timepoint,
        sum(case when group='A' and tte <=90 and event=1 then 1 else 0 end) as GroupA,
        sum(case when group='B' and tte <=90 and event=1 then 1 else 0 end) as GroupB
    from have
    union all
    select 
        'le 180' as Timepoint,
        sum(case when group='A' and tte <=180 and event=1 then 1 else 0 end) as GroupA,
        sum(case when group='B' and tte <=180 and event=1 then 1 else 0 end) as GroupB
    from have
    union all
    select 
        'le 365' as Timepoint,
        sum(case when group='A' and tte <=365 and event=1 then 1 else 0 end) as GroupA,
        sum(case when group='B' and tte <=365 and event=1 then 1 else 0 end) as GroupB
    from have;
quit;

proc print data=event_summary noobs;
run;

方案2:DATA步标记+PROC TABULATE汇总

先为每个观测标记是否符合各时间点的事件条件,再用制表过程快速生成结构化报表:

data have_flags;
    set have;
    /* 仅对发生事件的观测标记时间点符合情况,未发生事件的直接置0 */
    if event = 1 then do;
        flag_30  = (tte <= 30);
        flag_90  = (tte <= 90);
        flag_180 = (tte <= 180);
        flag_365 = (tte <= 365);
    end;
    else do;
        flag_30 = 0;
        flag_90 = 0;
        flag_180 = 0;
        flag_365 = 0;
    end;
run;

proc tabulate data=have_flags format=8.0;
    class group;
    var flag_30 flag_90 flag_180 flag_365;
    table 
        ('Timepoint'
         'le 30'  * flag_30.sum
         'le 90'  * flag_90.sum
         'le 180' * flag_180.sum
         'le 365' * flag_365.sum
        ),
        group=' ' * (GroupA='A' GroupB='B')
    / box='Timepoint';
run;

方案3:动态时间点处理(适合灵活调整时间点)

先创建时间点参数表,通过笛卡尔积关联原数据后批量统计,后续调整时间点只需修改参数表,无需改动统计代码:

/* 定义需要统计的时间点列表 */
data timepoints;
    length Timepoint $6;
    input Timepoint cutoff;
    datalines;
le 30   30
le 90   90
le 180  180
le 365  365
;
run;

/* 关联时间点与原数据,分组汇总累计事件数 */
proc sql;
    create table event_summary_dynamic as
    select 
        t.Timepoint,
        sum(case when h.group='A' and h.tte <= t.cutoff and h.event=1 then 1 else 0 end) as GroupA,
        sum(case when h.group='B' and h.tte <= t.cutoff and h.event=1 then 1 else 0 end) as GroupB
    from timepoints t cross join have h
    group by t.Timepoint, t.cutoff
    order by t.cutoff;
quit;

proc print data=event_summary_dynamic noobs;
run;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:10:39