SAS为纵向数据添加新观察

SAS为纵向数据添加新观察

问题描述:

我有一个SAS中的纵向数据集,其时间段可分为事件风险或无风险。不幸的是,一些时间段重叠,我想重新编码他们有一个完全不重叠的观测数据集。例如,数据集目前的样子:SAS为纵向数据添加新观察

Row 1: ID=123; Start=Jan 1, 1999; End=Dec 31, 1999; At_risk="Yes" 
Row 2: ID=123; Start=Feb 1, 1999; End=Feb 15, 1999; At_risk="No" 

我想看起来像数据集:

Row 1: ID=123; Start=Jan 1, 1999; End=Feb 1, 1999; At_risk="Yes" 
Row 2: ID=123; Start=Feb 1, 1999; End=Feb 15, 1999; At_risk="No" 
Row 3: ID=123; Start=Feb 15, 1999; End=Dec 31, 1999; At_risk="Yes" 

的思考?

+0

您是否拥有ETS授权? – Joe 2014-10-08 15:26:17

Vasja可能一直在建议像这样(日期级别)作为替代方案。

我这里假设你的纵向数据集阅读最新行将优先于重叠的日期范围内的任何其他行。如果情况并非如此,则酌情调整以下的优先级派生。

你确定你的开始和结束日期是正确的。您所需的输出仍有重叠的日期。 2月1日& 15都处于风险状态并且没有风险。您的结束日期应至少在下一个开始日期的前一天。不同一天。结束日期和开始日期应该是连续的。出于这个原因,编写一个能产生你想要的输出(有重叠日期)的解决方案是有问题的。以下解决方案基于不重叠的日期。您将需要修改它以包含重叠的日期根据您的要求的输出。

/*   Your longitudinal dataset . */ 
data orig; 
     format Id 16. Start End Date9.; 
     Id = 123;Start='1jan1999'd; End='31dec1999'd; At_risk="Yes";output; 
     Id = 123;Start='1feb1999'd; End='15feb1999'd; At_risk="No";output; 
run; 

/*   generate a row for each date between start and end dates. */ 
/*   Use row number (_n_) to assign priorioty. */ 
Data overlapping_dates; 
     set orig; 
     foramt date date9.; 
     priority = _n_; 
     do  date = start to end by 1; 
       output; 
     end; 
Run; 

/*   Get at_risk details for most recent read date according to priority. */ 
Proc sql; 
     create table non_overlapping_dates as 
     select id, date, at_risk 
     from overlapping_dates 
     group by  id, date 
     having priority eq max (priority) 
     order by  id, date 
     ; 
Quit; 


/* Rebuild longitudinal dataset . */ 
Data longitudinal_dataset 
    (keep= id start end at_risk) 
    ; 
     format id 16. Start End Date9. at_risk $3.; 

     set non_overlapping_dates; 
     by id at_risk notsorted; 

     retain start; 

    if first.at_risk 
     then start = date; 

/*  output a row to longitudinal dataset if at_risk is about to change or last row for id. */ 
     if  last.at_risk 
       then do; 
      end = date; 
      output; 
        end;      
Run; 
+0

工作完美,非常感谢! – 2014-10-10 00:29:43

这样的任务是练习调试程序逻辑和战斗数据的假设,玩旧/新值... 在我提供的确切示例的初始代码下面,肯定需要对实际数据进行一些调整。

万一有上超过电流下一个记录时间重叠,我不知道它是可行的这种方式(用合理的努力)。对于这种情况,您可能会更有效地使用将原始开始结束间隔分为日期级别,然后将细节汇总到新的间隔

data orig; 
format Id 16. Start End Date9.; 
Id = 123;Start='1jan1999'd; End='31dec1999'd; At_risk="Yes";output; 
Id = 123;Start='1feb1999'd; End='15feb1999'd; At_risk="No";output; 
run; 

proc sort data = orig; 
by ID Start; 
run; 

data modified; 
    format pStart oStart pEnd oEnd Date9.; 
    set orig; 
    length pStart pEnd 8 pAt_risk $3; 
    by ID descending End ; 

    retain pStart pEnd pAt_risk; 

    /* keep original values */ 
    oStart = Start; 
    oEnd = End; 
    oAt_risk = At_risk; 

    if first.id then do; 
     pStart = Start; 
     pEnd = End; 
     pAt_risk = At_risk; 
     /* no output */ 
    end; 
    else do; 
     if pAt_risk ne At_risk then do; 
      if Start > pStart then do; 
       put _all_; 
       Start = pStart; 
       End = oStart; 
       At_risk = pAt_risk; 
       output;/* first part of time span */ 
       Start = oStart; 
       End = oEnd; 
       At_risk = oAt_risk; 
       output;/* second part of time span */ 
       if (End < pEnd) then do; 
        Start = End; 
        End = pEnd; 
        At_risk = pAt_risk; 
        output; /*third part of time span */ 
        /* keep current values as previous record values */ 
        pStart = max(oStart, Start); 
        pEnd = End; 
        pAt_risk = At_risk; 
       end; 
      end; 
     end; 
    end; 
run; 

proc print;run; 
+0

是的,不幸的是,除了当前下一个记录之外还有其他重叠。虽然你们有关将时间间隔分成不同日期的建议很有用。谢谢! – 2014-10-10 00:31:22