Set title using macro and proc report - sas

I would like to create a macro to produce a report (proc report) for each datasets and include the title "Compulsion scale: Q6_#", but not sure how to add the title
%MACRO diff(var=);
%Let title = %var;
PROC REPORT DATA=table_&var.;
TITLE"CYBOCS COMPULSION SCALE: %var";
RUN;
%MEND diff;
OPTIONS MPRINT MLOGIC;
%diff(var=q6_1a);
%diff(var=q6_1b);
%diff(var=q6_2);
%diff(var=q6_3);
%diff(var=q6_4);
%diff(var=q6_5);
%diff(var=q6_6);
%diff(var=q6_7);
%diff(var=q6_date);

The parameter to a macro is a local macro variable. To reference the value of a macro variable use & in front of its name.
%MACRO diff(var=);
PROC REPORT DATA=table_&var.;
TITLE "CYBOCS COMPULSION SCALE: &var";
RUN;
%MEND diff;

Related

Conditional Formatting in SAS with Macros

Hi I'm trying to apply conditional formatting to a table in SAS. The conditional formatting will be highlighting data in columns (variables). If the field is "Y" then highlight green, else if the field is "N" then red.
The input table looks like this:
My goal is to have it looks something like this
I currently have this code in my macro:
%LET NVARS= 6;
%LET to_date= '01SEP2022'd;
%macro cf();
PROC REPORT DATA=work.process /*the data set input */ OUT=work.test1;
COLUMN SKU HIGH PRI COST_CTR
%DO i = 1 %TO &NVARS.;
SUPPORT&i.
%END;
%DO i =1 %TO &NVARS.;
DEFINE SUPPORT&i. / DISPLAY
STYLE (column)={just=center};
%END;
%DO i =1 %TO &NVARS.;
COMPUTE SUPPORT&i.;
IF SUPPORT&i. ='Y' THEN CALL DEFINE (_col_,'style','style={background=vilg}');
IF SUPPORT&i. ='N' THEN CALL DEFINE (_col_,'style','style={background=viypk}');
ENDCOMP;
%END;
RENAME
%DO i =1 %TO &NVARS.;
SUPPORT&i. = %SYSFUNC(INTNX(month,&to_date.,&I-1),monyy7)
%END;
RUN;
%MEND;
%cf();
For some reason it's erroring out and not doing the conditional formatting. I then want to export the output in excel. Any help is greatly appreciates from SAS gurus.
Personally, I would use PROC PRINT to do this instead of PROC REPORT.
Create a format to format Y as green, N as red
Use PROC PRINT to display information
Create labels dynamically instead of rename to display the months name dynamically.
Use ODS EXCEL to pipe the formatted output including colours directly to Excel (tested and it works).
proc format;
value $ support_fmt
'Y' = 'vilg'
'N' = 'viypk';
run;
ods excel file = '/home/fkhurshed/Demo1/demo.xlsx';
%macro cf;
%LET NVARS= 6;
%LET to_date= '01SEP2022'd;
proc print data=have label noobs;
var sku high_pri cost_ctr ;
var support1-support6 / style={background=$support_fmt.};
%do i=1 %to &nvars;
label support&i. = %sysfunc(intnx(month, &to_date, %eval(&i-1)), monyy7.);;
%end;
run;
%mend;
%cf;
ods excel close;

PROC REPORT within DATA in SAS

I am trying to do a simple thing - write a PROC REPORT procedure within a DATA sentence. My main idea is - if the condition in data step is true - lets execute PROC REPORT, if it is false - do not execute PROC REPORT. Any ideas? Code runs without errors for now, but I see that condition in IF statement is not applied and PROC REPORT is ececute despite the fact that condition is not fulfilled.
Thank you in Advance.
%let DATO = 13062016;
PROC IMPORT OUT= WORK.auto1 DATAFILE= "C:\Users\BC1554\Desktop\andel.xlsx"
DBMS=xlsx REPLACE;
SHEET="sheet1";
GETNAMES=YES;
RUN;
data want;
set WORK.auto1;
rownum=_n_;
run;
DATA tbl2;
SET want;
if (rownum => 1 and rownum <=6 ) then output work.tbl2 ;
RUN;
ODS NORESULTS;
ods LISTING close;
ODS RTF FILE="C:\Users\BC1554\Desktop\Statistik_andel_&DATO..rtf";
title "Statistics from monthly run of DK shares of housing companies (andelsboliger)";
data Tbl21 ;
set work.Tbl2;
where (DKANDEL='Daekning_pct_24052016' or DKANDEL='Daekning_pct_18042016') ;
difference = dif(Andel);
difference1 = dif(Total);
run;
data Tbl211 ;
set work.Tbl21;
where (DKANDEL='Daekning_pct_18042016') ;
run;
data Tbl2111 ;
set work.Tbl211;
where (DKANDEL='Daekning_pct_18042016') ;
if abs(difference) > 10 and abs (difference1) > 107 then ;
run;
proc report data= work.Tbl2 spanrows;
columns DKANDEL Andel Total Ukendt ;
title2 "-";
title3 "We REPORT numbers on p.4-5".;
title4 "-";
title5 "The models coverage";
title6 "Run date &DATO.";
footnote1 "Assets without currency code not included";
define DKANDEL / order;
define Andel / order;
define Total / order;
define Ukendt / order;
define DKANDEL/ display;
define Andel / display;
Compute DKANDEL;
call define (_col_,"style","style={background=orange}");
endcomp;
Compute Andel;
call define (_col_,"style","style={background=red}");
endcomp;
run; title; footnote1;
ODS RTF close;
ODS LISTING;
title;
run;
To conditionally execute code you need to use a macro so that you can use macro logic like %IF to conditionally generate the code.
But for your simple problem you can use a macro variable to modify the RUN; statement on your PROC REPORT step. Create a macro variable and set it to the value CANCEL when you don't want the step to run.
%let cancel=CANCEL;
...
if abs(difference) > 10 and abs (difference1) > 107 then call symputx('cancel','');
...
proc report ... ;
...
run &cancel ;
Simple example. Produce report if anyone is aged 13.
%let cancel=CANCEL;
data _null_;
set sashelp.class ;
if age=13 then call symputx('cancel',' ');
run;
proc report data=sashelp.class ;
run &cancel;
Tom's answer is a good one, and probably what I'd do. But, an alternative that is more exactly what you suggested in the question seems also appropriate.
The way you execute a PROC REPORT in a data step (or execute any non-data-step code in a data step) is with call execute. You can use call execute to execute a macro, or just a string of code; up to you how you want to handle it. I would make it a macro, because that makes development much easier (you can write the macro just like regular code, and you can test it independently).
Here's a simple example that is analogous to what Tom put in his answer.
%macro print_report(data=);
proc report data=&data.;
run;
%mend print_report;
data _null_;
set sashelp.class ;
if age=13 then do;
call execute('%print_report(data=sashelp.class)');
stop; *prevent it from donig this more than once;
end;
run;

SAS Proc Report Title Error

I have an issue where by the do loop creates my reports however the title page where the macro is listed doesn't reflect the correct naming convention each time.
It works for each of the bookmarks in PDF as well as the proc report itself. However the titles don't reflect correctly.
%macro PDF_T2(year=, age= );
proc sql noprint;
select distinct region, bh_type
into :region1 - :region14, :bh_type1 - :bh_type14
from table2_IP
;
quit;
/*%put &region1 &region2;*/
/*%put &bh_type1 &bh_type2;*/
ods escapechar '^';
ods pdf file="C:\PDFS\Table2.pdf" pdftoc=2 style=Custom;
options orientation=landscape missing=' '
topmargin=.25in
bottommargin=.25in
leftmargin=.25in rightmargin=.25in ;
ods proclabel " Inpatient Analysis By Plan ";
%do i=1 %to 4;
TITLE "^{style [JUST= C ]Table 2. Inpatient Utilization By Plan,}";
TITLE2 "^{style [JUST= C ]&&region&i. }" ;
Title3 "^{style [JUST= C ]Adult (21 to 64)}";
Title4 "^{style [JUST= C ]&&bh_type&i. Analysis}" ;
PROC REPORT DATA = Table2_IP contents="&&bh_type&i. Table: Inpatient`enter code here`
I would try making sure that you are using %local macro variables. If you have global macro variables floating around that could cause some surprising results.
I would also turn on MPRINT and look at the log to see what code is being generated. It will show the TITLE statements that the macro is generating.
Titles do not clear themselves, but every time your TITLE statement executes it will clear any existing titles.
I modified your code a bit to work on sashelp.prdsale, and it seems fine:
%macro titletest(dummy);
%local i region1 region2;
proc sql noprint;
select distinct region
into :region1 - :region2
from sashelp.prdsale
;
quit;
%put region1=&region1 region2=&region2;
%do i=1 %to 2;
title1 "Results for &&region&i";
proc print data=sashelp.prdsale;
where region="&&region&i";
run;
title1;
%end;
%mend;
options mprint;
%titletest()

How can I create SAS html files with names corresponding to a dataset field

I'm trying to create a file for each record in my SAS dataset. I have been able to succesfully do this using SAS ODS output by using the "newfile=page" option and then simply running a proc report on the dataset. The problem I'm having is that this results in gerneric, sequentially numbered file names (test, test1, test2, etc...). I'd like to name each file based on a variable in the dataset. In the example below, I'd like the file names to be titled based on the "seq_nbr" in the dataset.
ods html path = "C:\test\"
file = 'test.html'
contents = 'contents.html
frame = 'frame.html'
code = (url="C:\test\javascript.js")
newfile=page;
proc report data = test2 nowindows headline headskip;
column tDate tTime created_by cmtText;
by seq_nbr;
run;
You need a macro for this
%macro doit;
proc sql;
select count(*) into :n from test2 ;
quit;
%do i=1 %to &n;
data _null_;
if _n_=&i call symput('name',seq_nbr);
run;
proc export data=something outfile="&name";
run;
%end;
%mend;
%doit;

How to resolve a date macro variable in proc step

%macro example
%let begdate = ’01Nov2004’d;
%let enddate = ’30Nov2004’d;
proc sort data=test out=test2;
where date between &begdate and &enddate;
by date;
run;
%mend example;
This code gives me the error: ERROR: Syntax error while parsing WHERE clause.
However, when I simply replace &begdate and &enddate by corresponding values, it works.
I normally run mine like this:
%macro example
%let begdate = 01Nov2004;
%let enddate = 30Nov2004;
proc sort data=test out=test2;
where date between "&begdate"d and "&enddate"d;
by date;
run;
%mend example;
I simply remove any assumptions of a date format and refer to the macro variable in the code as a string. Hope this helps!!