DATA Step, Macro, Functions and more

using %sysfunc(cat() )

Reply
New Contributor
Posts: 3

using %sysfunc(cat() )

Hi,
I wrote a macro that creates macro variables of satistics  from proc NPAR1WAY and then inputs them into a data set called wilcox1 as below.There are 4 statistics wilstatk and pvalk k=1,..,4.
For some reason the loop goes all the way to k=5 and and the the resolve functoin tries to resolve &wilstat5 and &pval5 which don't exist. Can anyone tell me what might be causing this? Am I using the %sysfunc(cat() ) correctly?  

            data wilcox1;
                        %do k=1 %to 4;
                              %sysfunc(cat(wil_stat,&k)) = resolve('&&wilstat&k');
                              %sysfunc(cat(p_val,&k)) = resolve('&&pval&k');

                        %end;
                        output;
            run;
Thanks in advance.

PROC Star
Posts: 1,232

Re: using %sysfunc(cat() )

Not sure I'm following.

You have macro variables &wilstat1 &wilstat2 &wilstat3 &wilstat4 already with numeric values and you want to make a one record data set with variables with same name?

Using your approach, could be something like:

data wilcox1;

  %do k=1 %to 4;

    wil_stat&k=&&wilstat&k;

    p_val&k=&&p_val&k;

  %end;

run;

THat should generate code like:

data wilcox1;

  wil_stat1=10;

  p_val1=.10;

  wil_stat2=20;

  p_val2=.20;

  ...

run;

does that help?

Usually it's easier to the have procedure (NPAR1WAY) write the dataset for you, and manipulate that, rather than reading a lot of values into macro variables, only to put them back into a dataset.  Esp as you may be losing precision in the process.

Super User
Posts: 17,837

Re: using %sysfunc(cat() )

I don't see an error in how you're writing your cat functions, except I wonder why you need the resolve. Of course this all assumes you're in a macro, which you haven't shown.

To determine why you have errors in the first place, please post the log with your errors.

That being said, this is definitely not the most efficient or effective way of solving this problem.

If you want a more efficient solution, perhaps post the problem you're trying to solve.

Super User
Super User
Posts: 6,500

Re: using %sysfunc(cat() )

There isn't any need to use CAT() functions on macro variables.  Just reference the macro variables.

There isn't any need to use macro variables to move data from one dataset to another. Just use normal data step statements.

Can you show what the source dataset that you used to generate the macro variables looks like and what the final dataset your want to create looks like?

Super Contributor
Posts: 339

Re: using %sysfunc(cat() )

Explanation of your error as the proper fix was covered by Quentin

As with data step DO loops, the %DO also ends by iterating one beyond the end of loop criterion. So at the end of the %do loop &K is effectively 5. You can create a dataset with a do loop and not drop the counter variable and see for yourself.

So the issue with your code is that the macro first writes the following code during macro compilation phase and then executes this datastep code:

data wilcox1;

     wil_stat1=resolve('&&wilstat&k');

     ...

     p_val4=resolve('&&pval&k');

     output;

run;

That is, the resolve function resolves macro variable at data step execution phase rather than macro compilation phase as it was within your %sysfunc.

So timeliness wise, since the data step is executed after the macro code has been resolved, your code effectively turns into this conceptual hardcoded datastep with only macro variables:

data wilcox1;

     wil_stat1=&wilstat5;

     p_val1=&pval5;

     wil_stat1=&wilstat5;

     p_val1=&pval5;

     wil_stat1=&wilstat5;

     p_val1=&pval5;

     wil_stat1=&wilstat5;

     p_val1=&pval5;

     output;

run;

So the error lies in using the resolve function and the corrections were covered by Quentin and Reeza.

Ask a Question
Discussion stats
  • 4 replies
  • 3487 views
  • 1 like
  • 5 in conversation