2014-10-08 64 views
1

我有一個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

回答

0

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

0

這樣的任務是練習調試程序邏輯和戰鬥數據的假設,玩舊/新值... 在我提供的確切示例的初始代碼下面,肯定需要對實際數據進行一些調整。

萬一有上超過電流下一個記錄時間重疊,我不知道它是可行的這種方式(用合理的努力)。對於這種情況,您可能會更有效地使用將原始開始結束間隔分爲日期級別,然後將細節彙總到新的間隔

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

相關問題