BookmarkSubscribeRSS Feed
humenghu
Calcite | Level 5

I encountered a problem while I was studying SAS programming for clinical trials. I will just paste the problem here:

"

Using dataset DOSES, create a report showing all patients who changed dose during the study, and their actual dose at each visit. In this report indicate the extent of dose adjustment by creating a variable called DOSEADJ which takes the values
N (normal) if dose remains the same as at visit 1
R (reduced) if the dose is less than the previous dose
P (remains reduced) if the dose is the same as the previous dose, but the previous dose was reduced compared with visit 1

For example, patients 1 & 6 would appear in the report as below, but patients 4 & 5 would not be reported. Note PATIENT uniquely identifies the patient.

PATIENT    VISIT    ACTLDOSE    DOSEADJ

     1       1        32          N
               2        32          N
               3        16          R
               4        16          P
               5        16          P

      6       1        32          N
               2        16          R
               3         4           R

"

Suppose the raw data is just like the first three columns of the data shown above, how exactly can I generate the fourth column (DOSEADJ)? as required? I thought of using 'retain' and 'first.patient' etc, but have not been able to produce the code which can do the job.

Thanks!

 

11 REPLIES 11
Haikuo
Onyx | Level 15

What is the deal on "patients 4 & 5"? why are they not on the list? Does your raw data have  "patients 4 & 5"?

Update, if you don't care about "patients 4 & 5", all you want is to generate the indicator "doseadj", then try the following:

data have;

input PATIENT :$ VISIT ACTLDOSE ;

retain _p '' _d;

_p=coalescec(patient, _p);

patient=coalescec(patient,_p);

_lagd=lag(actldose);

if patient ne lag(patient) then do; DOSEADJ='N'; _d=actldose;end;

else do;

  if actldose=_d then DOSEADJ='N';

else if actldose < _lagd then DOSEADJ='R';

else if actldose = _lagd then DOSEADJ='P';

end;

drop _:;

cards;

  1 1 32 

  . 2 32 

  . 3 16 

  . 4 16 

  . 5 16 

  6 1 32 

  . 2 16 

  . 3 4 

;

Haikuo

humenghu
Calcite | Level 5

Thanks for the prompt feedback. Data of patient 4 and 5 are not important here.

Reeza
Super User

untested, and uses lag function to check previous record. This can help you get started:

data want;

set have;

by patient;

lagdose=lag(actldose);

lagadj=lag(doseadj);

if first.patient then do;

     lagdose=.;

     lagadj="";

end;

else do;

if lagdose=doseand lagadj="R" then doseadj="P";

else if lagdose<dose and lagadj="N" then doseadj="R";

build your conditions here to do the checks with more if else conditions

end;

run;

humenghu
Calcite | Level 5


I tried to complete your code by the following:

data have;

input patient visit actldose;

datalines;
1 1 32
1 2 32
1 3 16
1 4 16
1 5 16
2 1 32
2 2 16
2 3 4
;

run;

data want;
set have;
  by patient;

doseadj='';

lagged_actl=lag(actldose);

lagged_doseadj=lag(doseadj);

if first.patient then do;
  lagged_actl=.;
  lagged_doseadj='';
  end;


if lagged_actl>actldose then doseadj='R';
else if lagged_actl=actldose and (lagged_doseadj='R' or lagged_doseadj='P') then doseadj='P';
else if lagged_actl=actldose or lagged_actl=. then doseadj='N';

run;

but the variable lagged_doseadj remains blank. Can you help me to fix this problem?

allurai0412
Fluorite | Level 6

hi,

i guess due to below step................the variable 'lagged_doseadj'...will give blank....only..


Check whetherr this is missed in data reading...or in  'have' dataset.

data want;
set have;
  by patient;

doseadj='';

lagged_actl=lag(actldose);

lagged_doseadj=lag(doseadj);

....

.....

allurai0412
Fluorite | Level 6

hi,

check this ,,,,,please let me know the 'P' status is correctly working or not....


data want;
set have;
  by  patient;

lagged_actl=lag(actldose);

lagged_doseadj=lag(lagged_actl);

if first.patient then do;
  lagged_actl=.;
  lagged_doseadj='';
  end;


if lagged_actl>actldose then doseadj='R';
else if lagged_actl=actldose and lagged_doseadj>=actldose then doseadj='P';
else if lagged_actl=actldose or lagged_actl=. then doseadj='N';

run;

Regards

Allu

humenghu
Calcite | Level 5

I figured it out, the following should also work:

data have;

input patient visit actldose;

datalines;
1 1 32
1 2 32
1 3 16
1 4 16
1 5 16
2 1 32
2 2 16
2 3 4
;

run;


data want;
set have;
  by patient;


lagged_actl=lag(actldose);


if first.patient then do;
  lagged_actl=.;
  doseadj='N';
  end;

if lagged_actl>actldose then doseadj='R';

else if lagged_actl=actldose then 
        if doseadj='R' or doseadj='P' then doseadj='P';
        else doseadj='N';

retain doseadj;
run;

slchen
Lapis Lazuli | Level 10

data have;

input id visit dose ;

cards;

  1 1 32

  1 2 32

  1 3 16

  1 4 16

  1 5 16

  6 1 32

  6 2 16

  6 3  4

;

run;

proc sql;

       select id,visit,dose, case when flag=1 then 'N'

                                    when diff<0 then 'R'

                                    else 'P'

                                    end as Doseadj

       from (select *,ifn(dose=max(dose),1,0) as flag,

               (select a.dose-b.dose from have b where a.id=b.id and a.visit-b.visit=1) as diff 

       from have a);

quit;

Shenglin

humenghu
Calcite | Level 5

Thank you very much!

data_null__
Jade | Level 19

I don't think this is problem that needs LAGS or that is well suited to laged values..  It does need to remember the initial and last dose.  It also assumes the dose cannot increase.

data dose;
   infile cards missover;
  
input id visit dose @;
   do while(not missing(visit));
      output;
     
input visit dose @;
      end;
  
cards;
1 1 32  2 32  3 16  4 16  5 16 
6 1 32  2 16  3 4 
;;;;
   run;
data dose2;
   do until(last.id);
      set dose;
      by id dose notsorted;
     
if first.id then do;
         adj=
'N';
         ndose = dose;
        
end;
     
else if first.dose and dose lt ldose then adj='R';
     
else if dose eq ndose then adj = 'N';
     
else adj = 'P';
     
output;
      ldose = dose;
     
end;
  
drop ndose ldose;
   run;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 11 replies
  • 1074 views
  • 0 likes
  • 6 in conversation