%macro data_m(d);
%do j=1 %to &num_files_&d._rf;
data rf_&d._&j._n;
set rf_&d._&j. (where = (RecordType = "Parent" ));
number=_N_;
run;
%end;
%mend data_m;
%data_m(MAT);
Hi all,
When I run the above code i am getting this error. " A character operand was found in the %EVAL function or %IF condition where a numeric operand
is required. The condition was: &num_files_&d._rf
ERROR: The %TO value of the %DO J loop is invalid."
I don't know why the macro does not work when I use "&d." in num_files.Any ideas how to fix it?
Thanks,
Is there a macro variable that exists which has the value you would like to use as the upper limit for the %DO loop? What is the name of that macro variable?
Is it num_files_mat_rf ?
If so, then try:
%do j=1 %to &&num_files_&d._rf;
Is there a macro variable that exists which has the value you would like to use as the upper limit for the %DO loop? What is the name of that macro variable?
Is it num_files_mat_rf ?
If so, then try:
%do j=1 %to &&num_files_&d._rf;
First a generic debugging hint with macros: Options Mprint; set before executing macro code will show more details of generated statements. If your problems revolve around how macro variables are used you may want the SYMBOLGEN option as well.
Second: show an example of the non-macro code that worked.
Where are the macro variable(s) that start with NUM_FILES assigned?
And lastly test this and show us the result.
%macro dummy(d); %put num_files raw is &num_files_&d._rf;
%put num_files indirect is &&num_files_&d._rf; %mend; %dummy (MAT);
I suspect that you are going to need to build an indirect reference as &somevar&d.rtf is not going to resolve to a number that the %do loop is going to expect as MAT is not numeric.
Whenever you get an error in the log, you need to show us the ENTIRE log for that macro (or for the PROC or DATA step that has the error). Do not show us a small portion of the log, as you have done. (And this applies to all of your future questions here in the SAS Communities about errors in the log, SHOW US THE ENTIRE LOG FOR THAT STEP)
For macros which have errors in the log, it is also critical to first turn on the debugging option by running this code, and then running your macro again.
options mprint;
Then show us the ENTIRE log for the macro.
Your expression can never yield a number since it ends in the letters _rf, plus the macro variable D has been assigned the string MAT.
Perhaps you are trying to reference a macro variable named NUM_FILES_MAT_RF ?
You need to double the first &.
&&num_files_&d._rf
SAS will replace the && with & and remind itself to re-scan the resulting string for more macro variable references. So after the first pass the value has become:
&num_files_MAT_rf
So if that resolves to a digit string then your %DO loop should run.
But why not just eliminate the %DO loop altogether? Instead of writing N new datasets just write one new dataset that as the data from ALL of the original dataset.
%macro data_m(d);
data rf_all_&d. ;
set rf_&d._: (where = (RecordType = "Parent" )) indsname=indsname;
if indsname ne lag(indsname) then number=0;
number+1;
dsname=indsname;
run;
%mend data_m;
%data_m(MAT);
If there are other dataset names that start with the string RF_MAT_ then to only get ones with the numeric sffix in that range use:
set rf_&d._1 - rf_&d._&&num_files_&d._rf ....
You might need to add something like macro function like a %UNQUOTE() around that second one to prevent the macro processor and the SAS language process from confusing each other into seeing two separate names there.
set rf_&d._1 - %unquote(rf_&d._&&num_files_&d._rf) ....
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.