簡體   English   中英

如何計算SAS中連續值的最大數量

[英]How to count the maximum number of consecutive values in SAS

我有一個數據集,每個患者有一行,它包含有關患者服用 11 劑葯物的日期(格式化為 SAS 日期)的信息。 在數據集中,每天最多有一個劑量的葯物。 患者可以填充 1 到 11 個劑量之間的任何日期,並且沒有缺少信息的中間劑量(例如,如果填充了 Dose5,則根據定義填充了 Dose1-Dose4)。 我對獲得患者服用一劑葯物的最大連續天數感興趣。 這里有 5 個示例數據行。

data have;
    input PATIENT_ID Dose1 :ddmmyy10. Dose2 :ddmmyy10. Dose3 :ddmmyy10. Dose4 :ddmmyy10. Dose5 :ddmmyy10. Dose6 :ddmmyy10. Dose7 :ddmmyy10. Dose8 :ddmmyy10. Dose9 :ddmmyy10. Dose10 :ddmmyy10. Dose11;
    format Dose1 Dose2 Dose3 Dose4 Dose5 Dose6 Dose7 Dose8 Dose9 Dose10 Dose11 ddmmyy10.;
    cards;
          1          01/01/2020 01/02/2020 01/03/2020 01/04/2020 01/05/2020 01/06/2020 01/07/20  1/08/2020 01/09/2020 01/10/2020 01/11/2020
          2          01/01/2020 01/02/2020 01/03/2020 01/05/2020 01/06/2020
          3          01/02/2020 01/04/2020 01/06/2020 01/08/2020 01/10/2020 01/12/2020 01/14/2020 01/16/2020 01/18/2020
          4          01/03/2020 01/04/2020 01/05/2020 01/06/2020 01/07/2020 01/08/2020 01/09/2020  1/10/2020 01/12/2020 01/13/2020
          5          01/01/2020 01/07/2020 01/08/2020 01/10/2020
;
run;

我想獲得變量 MAX_CONSECUTIVE_DAYS:

data want;
    input PATIENT_ID MAX_CONSECUTIVE_DAYS Dose1 :ddmmyy10. Dose2 :ddmmyy10. Dose3 :ddmmyy10. Dose4 :ddmmyy10. Dose5 :ddmmyy10. Dose6 :ddmmyy10. Dose7 :ddmmyy10. Dose8 :ddmmyy10. Dose9 :ddmmyy10. Dose10 :ddmmyy10. Dose11;
    format Dose1 Dose2 Dose3 Dose4 Dose5 Dose6 Dose7 Dose8 Dose9 Dose10 Dose11 ddmmyy10.;
    cards;
          1          11                  01/01/2020 01/02/2020 01/03/2020 01/04/2020 01/05/2020 01/06/2020 01/07/20  1/08/2020 01/09/2020 01/10/2020 01/11/2020
          2          3                   01/01/2020 01/02/2020 01/03/2020 01/05/2020 01/06/2020              
          3          1                   01/02/2020 01/04/2020 01/06/2020 01/08/2020 01/10/2020 01/12/2020 01/14/2020 01/16/2020 01/18/2020
          4          8                   01/03/2020 01/04/2020 01/05/2020 01/06/2020 01/07/2020 01/08/2020 01/09/2020  1/10/2020 01/12/2020 01/13/2020
          5          2                   01/01/2020 01/07/2020 01/08/2020 01/10/2020
run;

到目前為止,我只能通過蠻力零碎地弄清楚如何做到這一點。

data bruteforce;
    set have;
    if Dose2 =. then MAX_CONSECUTIVE_DAYS=1;
      else if Dose3=. then
      do;
        if Dose2-Dose1=1 then MAX_CONSECUTIVE_DAYS=2;
          else MAX_CONSECUTIVE_DAYS=1;
      end;
      else if Dose4=. then
      do;
        if Dose3-Dose1=2 then MAX_CONSECUTIVE_DAYS=3;
          else if (Dose2-Dose1=1) or (Dose3-Dose2=1) then MAX_CONSECUTIVE_DAYS=2;
          else MAX_CONSECUTIVE_DAYS=1;
      end;
      else if Dose5=. then
      do;
        if Dose4-Dose1=3 then MAX_CONSECUTIVE_DAYS=4;
          else if (Dose3-Dose1=2) or (Dose4-Dose2=2) then MAX_CONSECUTIVE_DAYS=3;
          else if (Dose2-Dose1=1) or (Dose3-Dose2=1) or (Dose4-Dose3=1) then MAX_CONSECUTIVE_DAYS=2;
          else MAX_CONSECUTIVE_DAYS=1;
      end;
     /*And so on and so forth until accounting for rows where Dose10 is populated*/
 run;

但是,在我的實際工作中,有 200 多種葯物劑量,因此使用 if-then-else 語句執行一系列 do 循環是沒有意義的。 如果我不得不猜測,該解決方案可能與數組有關,但我不確定從哪里或如何開始。

首先,感謝您清楚地解釋了您的問題以及您迄今為止所嘗試的內容:-)

只是一個注釋。 我將您的輸入數據更改為具有 mmddyy10 信息/格式的日期。 我認為您想要的是連續計算天數而不是月數。

不管怎樣,試試這個。 隨意問

data have;
infile datalines missover;
input PATIENT_ID (Dose1 - Dose11)(:mmddyy10.);
format Dose: mmddyy10.;
cards;
1 01/01/2020 01/02/2020 01/03/2020 01/04/2020 01/05/2020 01/06/2020 01/07/2020 1/08/2020 01/09/2020 01/10/2020 01/11/2020
2 01/01/2020 01/02/2020 01/03/2020 01/05/2020 01/06/2020
3 01/02/2020 01/04/2020 01/06/2020 01/08/2020 01/10/2020 01/12/2020 01/14/2020 01/16/2020 01/18/2020
4 01/03/2020 01/04/2020 01/05/2020 01/06/2020 01/07/2020 01/08/2020 01/09/2020 1/10/2020 01/12/2020 01/13/2020
5 01/01/2020 01/07/2020 01/08/2020 01/10/2020
;

data want(drop=c i);
   set have;
   array dose {*} Dose:;
   c = 1;
   do i = 2 to dim(dose);
      if dose[i] - dose[i-1] = 1 then c + 1;
      else do;
         if c > mc then mc = c;
         c = 1;
      end;
   end;
   if mc = . then mc = c;
run;

結果:

PATIENT_ID Dose1...Dose11 mc 
1 ... 11 
2 ... 3 
3 ... 1 
4 ... 8 
5 ... 2 

正確,基於變量的array可以讓您迭代日期並計算最長的運行時間。

提示:盡可能使用變量名來表示值的內容。 dose<n>信息不如dose<n> dose_date<n>

穩健的計算將檢查或考慮邊緣情況,例如無劑量。

示例代碼:

從數組中提取值的 CPU 成本很小(可能可以忽略不計)。 假設數組被命名為x 循環內的計算x[index]-x[index-1]重復這樣的成本。
例如: x[5]−[x4]x[6]−x[5] 將提取的值存儲在變量中將減少重復成本。

數據集選項keep=是要輸出的變量的顯式列表。 或者,可以使用drop=_:排除名稱以_開頭的工作變量(在此示例中)。

data have;
infile datalines missover; input 
ID X1-X11; format _numeric_ 4.; datalines;
1 01 02 03 04 05 06 07 08 09 10 11
2 01 02 03 05 06
3 02 04 06 08 10 12 14 16 18
4 03 04 05 06 07 08 09 10 12 13
5 01 07 08 10
6 01
7
8 01 03 05 07 09 11 13 15 17 19 21
;

data want(keep=id x: rl_max);
  set have;
  array X X:;

  if not missing(x1) then _rl = 1;  /* preset if not an edge case */
  _p = x1;

  rl_max = _rl;

  do _index = 2 to dim(X);
    _q = X[_index]; /* store extracted value in worker variable */
    if missing(_q) then leave; /* iterate as little as needed */
     
    if _q - _p = 1 then /* consecutive */
      _rl = sum (_rl, 1);
    else do; /* gap, check and reset */
      if _rl > rl_max then rl_max = _rl;
      _rl = 1;
    end;

    _p = _q;  /* current to previous */
  end;

  if _rl > rl_max then rl_max = _rl;   /* no gaps */
run;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM