Hi everyone,
Hoping someone can help me. I've just about finished developing a macro code, but it isn't working for just one of my parameters (all others seem to be working). The line that I'm having trouble with is the Compute line (Compute percapita; percapita=(&Dx.sum/population)*10000). Based on my error messages, I have a feeling the computation is being stored somewhere and not being released when I execute a different macro parameter. I'm show the code and error message below.
When I run the code the first time it works (included the entire macro for reference):
%Macro PerCapitaReport(Dx);
Proc Report Data=Merge Missing;
Where &Dx=1;
Title "&Dx";
Column Province &Dx, (n sum pctn) Population PerCapita Age, Mean;
Define Province / group style (column) = Header;
Define &Dx / sum;
Define n / 'Count' f=comma6.;
Define sum / 'Sum';
Define pctn / 'Percent' f=percent9.2;
Define population / 'Population' group style (column) = Header f=comma12.;
Define percapita / computed 'Rate Per/10,000 Population' f=12.2;
Define age / 'Mean Age' f=9.;
Rbreak after / summarize style(summary) = Header;
Compute percapita; percapita=(&Dx.sum/population)*10000;
Endcomp;
Compute After; Province = 'Total';
Endcomp;
Run;
%Mend PerCapitaReport;
%PerCapitaReport(Allergies)Then when I try a different parameter (see code below)
%PerCapitaReport(Cancer)This is the error report:
1243 %PerCapitaReport(Cancer)
ERROR: The variable type of 'ALLERGIES.SUM'n is invalid in this context.
NOTE: The preceding messages refer to the COMPUTE block for PerCapita.
NOTE: Will not run due to compilation errors.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: There were 4984 observations read from the data set MERGE.
WHERE Cancer=1;
NOTE: PROCEDURE REPORT used (Total process time):
real time 0.06 seconds
cpu time 0.06 seconds
Appreciate any assistance anyone can offer. Thank you!
If you copy the code from your MPRINT and add just one dot, does that code work?
Proc Report Data=Merge Missing;
Where Diabetes=1;
Title "Diabetes";
Column Province Diabetes, (n sum pctn) Population PerCapita Age, Mean;
Define Province / group style (column) = Header;
Define Diabetes / sum;
Define n / 'Count' f=comma6.;
Define sum / 'Sum';
Define pctn / 'Percent' f=percent9.2;
Define population / 'Population' group style (column) = Header f=comma12.;
Define percapita / computed 'Rate Per/10,000 Population' f=12.2;
Define age / 'Mean Age' f=9.;
Rbreak after / summarize style(summary) = Header;
Compute percapita;
percapita=(Diabetes.sum/population)*10000; /* Add a dot here in Diabetes.sum*/
Endcomp;
Compute After;
Province = 'Total';
Endcomp;
Run;
If so, then my suggestion to add a dot should work. Since you are new to macro, one thing to remember is after you make a change to the code in the macro definition, you need to remember to highlight and submit the macro definition, so that the macro is compiled using the updated code.
If you still have a problem, please post longer log, where the log shows the macro definition and the macro call and the log messages after the macro call.
Thanks so much for the reply. Allergies is the name of a numeric category (binary 1=yes, 0=No). The code works the first time with any variable. It's the second time that I try and run it that it won't.
Hi,
The code you posted isn't matching up with the error you posted.
Can you please turn on OPTIONS MPRINT: and post the log from the first time you called the macro:
%PerCapitaReport(Allergies)
That macro call should generate:
Proc Report Data=Merge Missing;
Where Allergies=1;
Title "Allergies";
Column Province Allergies, (n sum pctn) Population PerCapita Age, Mean;
Define Province / group style (column) = Header;
Define Allergies / sum;
Define n / 'Count' f=comma6.;
Define sum / 'Sum';
Define pctn / 'Percent' f=percent9.2;
Define population / 'Population' group style (column) = Header f=comma12.;
Define percapita / computed 'Rate Per/10,000 Population' f=12.2;
Define age / 'Mean Age' f=9.;
Rbreak after / summarize style(summary) = Header;
Compute percapita; percapita=(Allergiessum/population)*10000; /*Note the problem on this line*/
Endcomp;
Compute After; Province = 'Total';
Endcomp;
Run;
Which I expect would error, because it will look for a variable named Allergiessum which I assume doesn't exist.
I would start there as a first step. And get it working for one variable. After that, if it doesn't work for a different variable, copy the code from the log (showed by the MPRINT) into your code window and try submitting it. It's either to debug non-macro code than macro code.
I don't use COMPUTE blocks a lot, but I think you need a dot in your code for Allergies.sum. When you reference a macro variable a dot and the end of the macro variable name indicates the end of the macro variable. That dot is part of the macro language, it is not a SAS language dot. If you want a SAS language dot, you need to type a second dot, i.e.:
Compute percapita; percapita=(&Dx..sum/population)*10000;
Good morning and thank you so much for your help Quentin. I've turned on OPTIONS MPRINT as you directed, and this is log report after calling the macro. I also did try the second dot, but that didn't make a difference. It's definitely just this one part of the code that seems to be the issue (where the call removes the decimal from the code percapita =(&Dx.sum/population)*10000 changes to percapita=(Diabetessum/population)*10000;
I'm just at a loss of what to do (also still a beginning learner. Background is in nursing actually ... but doing my best 🙂 ).
56 %PerCapitaReport(Diabetes)
NOTE: Writing HTML Body file: sashtml.htm
MPRINT(PERCAPITAREPORT): Proc Report Data=Merge Missing;
MPRINT(PERCAPITAREPORT): Where Diabetes=1;
MPRINT(PERCAPITAREPORT): Title "Diabetes";
MPRINT(PERCAPITAREPORT): Column Province Diabetes, (n sum pctn) Population PerCapita Age, Mean;
MPRINT(PERCAPITAREPORT): Define Province / group style (column) = Header;
MPRINT(PERCAPITAREPORT): Define Diabetes / sum;
MPRINT(PERCAPITAREPORT): Define n / 'Count' f=comma6.;
MPRINT(PERCAPITAREPORT): Define sum / 'Sum';
MPRINT(PERCAPITAREPORT): Define pctn / 'Percent' f=percent9.2;
MPRINT(PERCAPITAREPORT): Define population / 'Population' group style (column) = Header
f=comma12.;
MPRINT(PERCAPITAREPORT): Define percapita / computed 'Rate Per/10,000 Population' f=12.2;
MPRINT(PERCAPITAREPORT): Define age / 'Mean Age' f=9.;
MPRINT(PERCAPITAREPORT): Rbreak after / summarize style(summary) = Header;
MPRINT(PERCAPITAREPORT): Compute percapita;
MPRINT(PERCAPITAREPORT): percapita=(Diabetessum/population)*10000;
MPRINT(PERCAPITAREPORT): Endcomp;
MPRINT(PERCAPITAREPORT): Compute After;
MPRINT(PERCAPITAREPORT): Province = 'Total';
MPRINT(PERCAPITAREPORT): Endcomp;
MPRINT(PERCAPITAREPORT): Run;
NOTE: Variable Diabetessum is uninitialized.
NOTE: Missing values were generated as a result of performing an operation on missing values.
Each place is given by: (Number of times) at (Line):(Column).
14 at 1:24
NOTE: There were 44882 observations read from the data set MERGE.
WHERE Diabetes=1;
NOTE: PROCEDURE REPORT used (Total process time):
real time 0.75 seconds
cpu time 0.23 seconds
NOTE: Variable Diabetessum is uninitialized.
In PROC REPORT, you can't use a variable unless it is in the COLUMNS statement, and in the COLUMNS it must be to the left of the variable you are trying to compute.
Column Province diabetessum Diabetes, (n sum pctn) Population PerCapita Age, Mean;
You would probably also need
define diabetessum/noprint;
Thank you Paige. The diagnosis variable is already defined (Define &Dx / sum;). The diabetessum isn't a variable in my code (it's incorrectly generated when I call the macro because the decimal place gets dropped.
The code works without the Macro.
Appreciate your help 🙂
@agille05 wrote:
it's incorrectly generated when I call the macro because the decimal place gets dropped.
This is because a dot within a string terminates the name of a macro variable. This is needed so you can build strings out of variable and fixed parts.
Quick and simple example:
%let a = x;
%let b = y;
/* this works */
%let c = &a._&b.;
%put &=c.;
/* this does not work */
%let c = &a_&b;
/* this works, and leaves a dot in the string */
%let c = &a..&b.;
%put &=c.;
See Maxim 48.
So your COMPUTE block must be
compute percapita;
percapita = (&Dx..sum / population) * 10000;
endcomp;
Blanks (whitespace) help in making code more readable.
If you copy the code from your MPRINT and add just one dot, does that code work?
Proc Report Data=Merge Missing;
Where Diabetes=1;
Title "Diabetes";
Column Province Diabetes, (n sum pctn) Population PerCapita Age, Mean;
Define Province / group style (column) = Header;
Define Diabetes / sum;
Define n / 'Count' f=comma6.;
Define sum / 'Sum';
Define pctn / 'Percent' f=percent9.2;
Define population / 'Population' group style (column) = Header f=comma12.;
Define percapita / computed 'Rate Per/10,000 Population' f=12.2;
Define age / 'Mean Age' f=9.;
Rbreak after / summarize style(summary) = Header;
Compute percapita;
percapita=(Diabetes.sum/population)*10000; /* Add a dot here in Diabetes.sum*/
Endcomp;
Compute After;
Province = 'Total';
Endcomp;
Run;
If so, then my suggestion to add a dot should work. Since you are new to macro, one thing to remember is after you make a change to the code in the macro definition, you need to remember to highlight and submit the macro definition, so that the macro is compiled using the updated code.
If you still have a problem, please post longer log, where the log shows the macro definition and the macro call and the log messages after the macro call.
Awesome. That was totally it. I didn't realize I had to run the macro after the change (I'm so sorry to have bothered you all... but so appreciate the assistance! You've made my Friday. Thank you!
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.