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!
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
Thanks for the prompt feedback. Data of patient 4 and 5 are not important here.
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;
Thanks!
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?
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);
....
.....
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
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;
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
Thank you very much!
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.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.