I am creating a output using proc report, and below is the codes. I have 20 variables, for which i have to repeat the same step (compute block).
proc report data = final_lab;
column subject RFSTDAT_DER_RAW SCREEN C1D1 C1D3 C1D8 C1D15 C1D22 C1D29 C1D36 C2D1 C2D3 C2D8 C2D15 C2D22 C2D29 C2D36 C3D1 C3D8 C3D15 C3D22 C4D1 C4D8 C4D15 C4D22 C5D1 C6D1 C7D1 C8D1 C9D1 C10D1 CXD1 ;
define Subject / Display 'Subject' ;
Define RFSTDAT_DER_RAW / Display 'First Dose Date';
Define Screen / Display 'Screening';
Define C1D1 / Display 'Cycle 1 Day1' ;
compute C1D1;
if C1D1 = 'ND' then
call define('C1D1 ', "style", "style=[background=grey]");
else if C1D1 LE 1 then
call define('C1D1 ', "style", "style=[background=lightyellow]");
else if C1D1 >= 1 and C1D1 =<2 then
call define('C1D1 ', "style", "style=[background=lightgreen]");
else if C1D1 >= 3 and C1D1 < 6then
call define('C1D1 ', "style", "style=[background=orange]");
else if C1D1 >= 6 and C1D1 < 8 then
call define('C1D1 ', "style", "style=[background=lightblue]");
else if C1D1 >= 8 then
call define('C1D1 ', "style", "style=[background=red]");
endcomp;
run;
this compute block must be repeated for all the rest of the variable (C1D3 C1D8 C1D15 C1D22 C1D29 C1D36 C2D1 C2D3 C2D8 C2D15 C2D22 C2D29 C2D36 C3D1 C3D8 C3D15 C3D22 C4D1 C4D8 C4D15 C4D22 C5D1 C6D1 C7D1 C8D1 C9D1 C10D1 CXD1 ) ,tried doing do loop but the variable name is not in sequence order so I was unbale to do so.
is there a way to automate this for the reminder of the variable?
Try the below code, not tested due to lack of data, but should work
%let visits= C1D1 C1D3 C1D8 C1D15 C1D22 C1D29 C1D36 C2D1 C2D3 C2D8 C2D15 C2D22 C2D29 C2D36 C3D1 C3D8 C3D15 C3D22 C4D1 C4D8 C4D15 C4D22 C5D1 C6D1 C7D1 C8D1 C9D1 C10D1 CXD1;
%let labels= Cycle 1 Day1/Cycle 1 Day3/Cycle 1 Day8/Cycle 1 Day15...;
%macro report;
proc report data = final_lab;
column subject RFSTDAT_DER_RAW SCREEN &visits;
define Subject/ display 'Subject' ;
define RFSTDAT_DER_RAW/ display 'First Dose Date';
define Screen/ display 'Screening';
%let num= %sysfunc(countw(&visits));
%do i= 1 %to #
%let visit= %scan(&visits, &i);
%let label= %scan(&visits, &i, /);
define &visit/ display "&label" ;
compute &visit;
if &visit = 'ND' then call define("&visit", "style", "style=[background=grey]");
else if &visit LE 1 then call define("&visit", "style", "style=[background=lightyellow]");
else if &visit >= 1 and C1D1 =<2 then call define("&visit", "style", "style=[background=lightgreen]");
else if &visit >= 3 and C1D1 < 6 then call define("&visit", "style", "style=[background=orange]");
else if &visit >= 6 and C1D1 < 8 then call define("&visit", "style", "style=[background=lightblue]");
else if &visit >= 8 then call define("&visit", "style", "style=[background=red]");
endcomp;
%end;
run;
%mend;
%report;
compute C1D1;
if C1D1 = 'ND' then
call define('C1D1 ', "style", "style=[background=grey]");
else if C1D1 LE 1 then
call define('C1D1 ', "style", "style=[background=lightyellow]");
else if C1D1 >= 1 and C1D1 =<2 then
call define('C1D1 ', "style", "style=[background=lightgreen]");
else if C1D1 >= 3 and C1D1 < 6then
call define('C1D1 ', "style", "style=[background=orange]");
else if C1D1 >= 6 and C1D1 < 8 then
call define('C1D1 ', "style", "style=[background=lightblue]");
else if C1D1 >= 8 then
call define('C1D1 ', "style", "style=[background=red]");
endcomp;
Instead of the above, use custom formats instead of hard-coded background colors inside IF / THEN / ELSE, much less typing
See https://www.lexjansen.com/wuss/2006/tutorials/TUT-Carpenter.pdf, pages 1–3
To turn this into a macro that works across many variables, assuming as above you have created a custom format named CUSTOMF.
THIS CODE IS UNTESTED
%macro dothis;
%let varnames = C1D1 C1D3 C1D8 C1D15 C1D22 C1D29 C1D36 C2D1 C2D3 C2D8 C2D15 C2D22 C2D29 C2D36 C3D1 C3D8 C3D15 C3D22 C4D1 C4D8 C4D15 C4D22 C5D1 C6D1 C7D1 C8D1 C9D1 C10D1 CXD1;
proc report data = final_lab;
column subject RFSTDAT_DER_RAW SCREEN &varnames;
define Subject / Display 'Subject' ;
define RFSTDAT_DER_RAW / Display 'First Dose Date';
define Screen / Display 'Screening';
%do i=1 %to %sysfunc(countw(&varnames));
%let thisvarname=%scan(&varnames,&i,%str( ));
%let cycle=%substr(&thisvarname,2,1);
%let day=%substr(&thisvarname,4);
define &thisvarname/ Display "Cycle &cycle Day &day" ;
compute &thisvarname;
call define(_col_,'style',"style=[background=customf.]");
endcompute;
%end;
run;
%mend dothis;
%dothis
Also from now on, please consider indenting your code as above. Your eyeballs will thank you, and your coding will improve (likely you will make fewer errors because of the benefits of indenting).
Thank you very much for the reply, the link below is not working, could you please resend it to me, I would like to read and learn from it and will use it for further improvising my output
Remove the comma which was accidentally placed at the end of the link.
Try the below code, not tested due to lack of data, but should work
%let visits= C1D1 C1D3 C1D8 C1D15 C1D22 C1D29 C1D36 C2D1 C2D3 C2D8 C2D15 C2D22 C2D29 C2D36 C3D1 C3D8 C3D15 C3D22 C4D1 C4D8 C4D15 C4D22 C5D1 C6D1 C7D1 C8D1 C9D1 C10D1 CXD1;
%let labels= Cycle 1 Day1/Cycle 1 Day3/Cycle 1 Day8/Cycle 1 Day15...;
%macro report;
proc report data = final_lab;
column subject RFSTDAT_DER_RAW SCREEN &visits;
define Subject/ display 'Subject' ;
define RFSTDAT_DER_RAW/ display 'First Dose Date';
define Screen/ display 'Screening';
%let num= %sysfunc(countw(&visits));
%do i= 1 %to #
%let visit= %scan(&visits, &i);
%let label= %scan(&visits, &i, /);
define &visit/ display "&label" ;
compute &visit;
if &visit = 'ND' then call define("&visit", "style", "style=[background=grey]");
else if &visit LE 1 then call define("&visit", "style", "style=[background=lightyellow]");
else if &visit >= 1 and C1D1 =<2 then call define("&visit", "style", "style=[background=lightgreen]");
else if &visit >= 3 and C1D1 < 6 then call define("&visit", "style", "style=[background=orange]");
else if &visit >= 6 and C1D1 < 8 then call define("&visit", "style", "style=[background=lightblue]");
else if &visit >= 8 then call define("&visit", "style", "style=[background=red]");
endcomp;
%end;
run;
%mend;
%report;
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.