Hello,
I'm creating subject profiles and I want to know how to apply the subject (patient) id into all proc reports in one ODS pdf output. Right now there are only 20 subjects and I manually enter them at the top (highlighted in pink) to make one sas program for all subjects. I would like to have one program to run all subject profiles. I did make a global program that runs all the individual subject profiles, but this study is growing and I would like something simplier. Any help is greatly appreciated. Here is my code:
%let ptno = 018 -1007;
%let subj = where patient="&ptno";
goptions device=actximg;
ods listing close;
options orientation=landscape;
ods pdf file="&path_out\patient profiles_018-1007_&rundate..pdf" style=conatus;
proc report data=ae01 nowd headskip split='\';
title4 height=10pt justify=left "Subject &ptno" height=10pt justify=center 'Adverse Events';
column patient aeno path aeterm aestdat aesttim aeendat aeentim aeser_display aesev_display
aerel1_display aerel2_display aeacn3_display aeacnoth_display aeout_display;
&subj;
define patient / style=[just=c vjust=t cellwidth=20mm] display "Subject ID" ;
define aeno / order noprint;
define path / style=[just=l vjust=t cellwidth=20mm] display "Path";
define aeterm / style=[just=l vjust=t cellwidth=50mm] order id;
define aestdat / style=[just=c vjust=t cellwidth=25mm] page;
define aesttim / style=[just=c vjust=t cellwidth=25mm];
define aeendat / style=[just=c vjust=t cellwidth=25mm];
define aeentim / style=[just=c vjust=t cellwidth=25mm];
define aeser_display / style=[just=c vjust=t cellwidth=25mm] display "Serious AE\ (SAE)" page;
define aesev_display / style=[just=l vjust=t cellwidth=25mm] display "Severity";
define aerel1_display / style=[just=l vjust=t cellwidth=25mm] display "Relationship\ to Toca 511";
define aerel2_display / style=[just=l vjust=t cellwidth=25mm] display "Relationship\ to Toca FC";
define aeacn3_display / style=[just=l vjust=t cellwidth=45mm] display "Action Taken\ to Treat Event" page;
define aeacnoth_display / style=[just=l vjust=t cellwidth=45mm] display "Other, Action Taken";
define aeout_display / style=[just=l vjust=t cellwidth=50mm] display "Outcome";
run;
proc report data=toc6.ae1a nowd headskip split='\';
title4 height=10pt justify=left "Subject &ptno" height=10pt justify=center 'Adverse Events - Fever';
column patient path ae1stdat ae1sttim ae1endat ae1entim ae1yn1_display ae1res2_display ae1resu2_display
ae1et_display ae1etoth_display;
&subj;
define patient / style=[just=c vjust=t cellwidth=20mm] display "Subject ID" ;
define path / style=[just=l vjust=t cellwidth=20mm] display "Path" order id;
define ae1stdat / style=[just=c vjust=t cellwidth=25mm];
define ae1sttim / style=[just=c vjust=t cellwidth=25mm];
define ae1endat / style=[just=c vjust=t cellwidth=25mm];
define ae1entim / style=[just=c vjust=t cellwidth=25mm];
define ae1yn1_display / style=[just=l vjust=t cellwidth=25mm] display "Patient's Temperature Recorded?";
define ae1res2_display / style=[just=l vjust=t cellwidth=25mm] display "Highest Temperature Start to End";
define ae1resu2_display / style=[just=l vjust=t cellwidth=25mm] display "Unit";
define ae1et_display / style=[just=l vjust=t cellwidth=50mm] display "Etiology";
define ae1etoth_display / style=[just=l vjust=t cellwidth=50mm];
run;
ods pdf close;
ods listing;
If the results for each patient have to be in individual PDF files, then you have to write a loop that loops through all possible patients.
/**** UNTESTED CODE ****/
%macro dothis;
proc sql noprint;
select distinct patient into :patients separated by '~' from ae01;
quit;
%do i=1 %to &sqlobs;
%let this_patient = %scan(&patients,&i,~);
ods pdf file="&path_out\patient profiles_&this_patient._&rundate..pdf"
style=conatus;
proc report data=ae01(where=(patient="&this_patient")) nowd headskip ...;
...
run;
ods pdf close;
%end;
%mend;
%dothis
If the results for each patient have to be in individual PDF files, then you have to write a loop that loops through all possible patients.
/**** UNTESTED CODE ****/
%macro dothis;
proc sql noprint;
select distinct patient into :patients separated by '~' from ae01;
quit;
%do i=1 %to &sqlobs;
%let this_patient = %scan(&patients,&i,~);
ods pdf file="&path_out\patient profiles_&this_patient._&rundate..pdf"
style=conatus;
proc report data=ae01(where=(patient="&this_patient")) nowd headskip ...;
...
run;
ods pdf close;
%end;
%mend;
%dothis
Hello,
First put the code in a macro and then apply on the varying parameter. You can create a list of parameters and then can call the macro using call execute.
Example (not tested);
%Macro Pt_report(ptno);
goptions device=actximg;
ods listing close;
options orientation=landscape;
ods pdf file="&path_out\patient profiles_&ptno_&rundate..pdf" style=conatus;
proc report data=ae01 nowd headskip split='\';
title4 height=10pt justify=left "Subject &ptno" height=10pt justify=center 'Adverse Events';
column patient aeno path aeterm aestdat aesttim aeendat aeentim aeser_display aesev_display
aerel1_display aerel2_display aeacn3_display aeacnoth_display aeout_display;
where patient="&ptno";
define patient / style=[just=c vjust=t cellwidth=20mm] display "Subject ID" ;
define aeno / order noprint;
define path / style=[just=l vjust=t cellwidth=20mm] display "Path";
define aeterm / style=[just=l vjust=t cellwidth=50mm] order id;
define aestdat / style=[just=c vjust=t cellwidth=25mm] page;
define aesttim / style=[just=c vjust=t cellwidth=25mm];
define aeendat / style=[just=c vjust=t cellwidth=25mm];
define aeentim / style=[just=c vjust=t cellwidth=25mm];
define aeser_display / style=[just=c vjust=t cellwidth=25mm] display "Serious AE\ (SAE)" page;
define aesev_display / style=[just=l vjust=t cellwidth=25mm] display "Severity";
define aerel1_display / style=[just=l vjust=t cellwidth=25mm] display "Relationship\ to Toca 511";
define aerel2_display / style=[just=l vjust=t cellwidth=25mm] display "Relationship\ to Toca FC";
define aeacn3_display / style=[just=l vjust=t cellwidth=45mm] display "Action Taken\ to Treat Event" page;
define aeacnoth_display / style=[just=l vjust=t cellwidth=45mm] display "Other, Action Taken";
define aeout_display / style=[just=l vjust=t cellwidth=50mm] display "Outcome";
run;
proc report data=toc6.ae1a nowd headskip split='\';
title4 height=10pt justify=left "Subject &ptno" height=10pt justify=center 'Adverse Events - Fever';
column patient path ae1stdat ae1sttim ae1endat ae1entim ae1yn1_display ae1res2_display ae1resu2_display
ae1et_display ae1etoth_display;
where patient="&ptno";
define patient / style=[just=c vjust=t cellwidth=20mm] display "Subject ID" ;
define path / style=[just=l vjust=t cellwidth=20mm] display "Path" order id;
define ae1stdat / style=[just=c vjust=t cellwidth=25mm];
define ae1sttim / style=[just=c vjust=t cellwidth=25mm];
define ae1endat / style=[just=c vjust=t cellwidth=25mm];
define ae1entim / style=[just=c vjust=t cellwidth=25mm];
define ae1yn1_display / style=[just=l vjust=t cellwidth=25mm] display "Patient's Temperature Recorded?";
define ae1res2_display / style=[just=l vjust=t cellwidth=25mm] display "Highest Temperature Start to End";
define ae1resu2_display / style=[just=l vjust=t cellwidth=25mm] display "Unit";
define ae1et_display / style=[just=l vjust=t cellwidth=50mm] display "Etiology";
define ae1etoth_display / style=[just=l vjust=t cellwidth=50mm];
run;ods pdf close;ods listing;
%Mend pt_report;
proc sql;
create table ptno_for_run as
select distinct ptno from have;
quit;
data _null_;
set ptno_for_run;
Call Execute(cats('%pt_report(',Strip(ptno),');'));
run;
Thanks Suryakiran,
I changed the ptno to patient because that's the variable name. I run the updated program and got this message:
Any suggestions?
Poste code and errors into a code box instead of a picture. Use the forum's {I} icon to open the box. Then just copy and paste from the log. Best is to include as a minimum an entire data step or procedure call. Some errors are actually caused by something on a previous line and the line reported with an error may not contain the actual reason.
Also with text of the code we can edit the text to show what is needed instead of having to type a description like: it looks like you are missing a comma following the "strip(patient)" part of your code.
You don't need to use strip with CATS. Note from the documentation:
Removes leading and trailing blanks, and returns a concatenated character string.
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 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.