Binnnnn5
Binnnnn5

Reputation: 187

How to flag out the first record of TEMP back to normal?

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

Answers (2)

whymath
whymath

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

stallingOne
stallingOne

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

  1. use a dummy variable dontflaganymore to know if we already flagged the temperature (as being <37).

  2. retain than dummy variable to be able to use it in the next line.

  3. and reset that variable each time we have a new ID (by ID; if first.ID then do;)

Upvotes: 2

Related Questions