Reputation: 187
Flag the first record of TEMP back to normal(no more than 37C).
data temp;
input ID $ SEQ $ TEMP ;
datalines;
001 1 37.3
001 2 37.2
001 3 36.3
001 4 37.3
001 5 36.9
001 6 36.9
002 1 37.3
002 2 37.2
002 3 36.3
002 4 35.3
002 5 36.9
002 6 36.9
003 1 37.3
003 2 37.1
003 3 38.2
003 4 39.3
004 1 36.3
004 2 38.2
004 3 36.5
004 4 36.4
;
run;
Here is the question:
How to flag out the first record of TEMP back to normal(no more than 37C).
Here are 2 patients each with 6 temperature observations, 2 patients each with 4 temperature observations. If a patient's temperature finally gets to normal (last temperature < 37), then, flag out the first record of temp that smaller than 37.
Take the ID = 001 patient as example.
001 1 37.3
001 2 37.2
001 3 36.3
001 4 37.3
001 5 36.9
001 6 36.9
As the 6th temp record is 36.9, smaller than 37, finally get back to normal, then, flag out the 5th record.
001 1 37.3 0
001 2 37.2 0
001 3 36.3 0
001 4 37.3 0
001 5 36.9 1
001 6 36.9 0
For the patient ID = 003.
003 1 37.3
003 2 37.1
003 3 38.2
003 4 39.3
As this patient's last temp is larger than 37. The results should be like:
003 1 37.3 0
003 2 37.1 0
003 3 38.2 0
003 4 39.3 0
This question really frustrated me. I would be very grateful for your help, many thanks.
Upvotes: 1
Views: 48
Reputation: 1394
Very good question, I have been working on this, too.
The secret is lookup from last to first.
data TempRst;
set Temp nobs = nobs;
by ID SEQ;
LagTemp = Lag(Temp);
if first.ID then LagTemp = .;
do i = nobs to _N_ by -1;
set Temp(rename=(ID=IDTmp SEQ=SEQTmp Temp=TempTmp)) point = i;
if ID = IDTmp and SEQ < SEQTmp and TempTmp > 37 then do;
Flag = 0;
leave;
end;
if ID = IDTmp and SEQ < SEQTmp and Temp < 37 and LagTemp > 37 then Flag = 1;
end;
Flag = coalesce(Flag,0);
drop IDTmp SEQTmp TempTmp LagTemp;
run;
And leave
statement is very important to prevent to continue searching after finding one observation having Temp
grater than 37.
Upvotes: 1
Reputation: 4006
I got it working with this.
data temp;
set temp;
retain dontflaganymore;
by ID;
if first.ID then dontflaganymore=0;
if TEMP<37 AND not dontflaganymore then do; flag=1; dontflaganymore=1; end;
else flag=.;
drop dontflaganymore;
run;
The idea is to
use a dummy variable dontflaganymore
to know if we already flagged the temperature (as being <37).
retain than dummy variable to be able to use it in the next line.
by ID; if first.ID then do;
)Upvotes: 2