Help using Base SAS procedures

What is wrong in my macro code?

Reply
Contributor
Posts: 27

What is wrong in my macro code?

I have the following macro and macro call. I only put in the relevant parts - I've verified my datastep code to work for individual values of "param" and "header" outside of the macro.

First I have a list called paramlist (defined below) composed of words, separated by spaces. I also have another list composed of phrases, called headerlist. Each phrase is separated by commas.

%macro CreateLabTab(paramlist,headerlist);

%let i=1;

%do i = 1 %to %sysfunc(countw("&paramlist."));

%let param=%scan(&paramlist., &i," ");

%let header=%scan(&headerlist., &i, ",");

************

**********Data step and proc report step that only use &param and &header once**************88

************

%mend;

%let paramlist =

ALK_PHOS_SER 

AST_SGOT_SER

;

%let headerlist=

Alkaline phosphatase (U/L),

ALT (mg/dL)

;

%CreateLabTab(&paramlist,&headerlist);

I'm getting ERROR: More positional parameters found than defined.

What could be the issue?

Thanks,

John

Super User
Posts: 5,255

Re: What is wrong in my macro code?

Valued Guide
Posts: 3,208

Re: What is wrong in my macro code?

remembers me of: Macro quoting made easy - SAS Users

---->-- ja karman --<-----
Contributor
Posts: 27

Re: What is wrong in my macro code?

Thank you. That fixed the ERROR issue. SAS now recognizes the phrases using commas.

Now I'm having trouble passing each value in paramlist into param. More details:

%macro CreateLabTab(paramlist,headerlist);

%let i=1;

%do i = 1 %to %sysfunc(countw("&paramlist."));

%let param=%scan(&paramlist., &i);

%let header=%scan(&headerlist., &i, ",");

data labtabs;

  merge data1 data2;

  by pt;

  if LPARM = "&param";

*********FLUFF******

run;

proc report nowd data=labtab2 headline headskip split='/';

  column ('Patient' idvar) ("Title" groupnum) ("&header" time, (lvalue))  dummy;

  define idvar/ group order = data left '';

  define groupnum/group order = data center '';

  define time/across center '' order = data;

  define lvalue/ center '';

  define dummy/ noprint;

run;

%let i=%eval(&i+1);

%end;

%mend;

%CreateLabTab(&paramlist,%bquote(&headerlist));

I don't get any errors. However, my dataset labtabs is empty. The variable LPARM is a character variable. That is why I passed &param in quotes.

Thanks,

John

Super User
Posts: 5,255

Re: What is wrong in my macro code?

Troubleshooting this kind of problem over a forum is hard.

Try setting MLOGIC SYMBOLGEN and MPRINT options, along with strategically placed %put's to see ehat is (not) happening).

Data never sleeps
Super User
Posts: 10,466

Re: What is wrong in my macro code?

Is the data set empty for all values of &param?

I would suggest you may have an issue with case.

Try

if upcase(LPARM) =upcase( "&param");

For example if you passed the word smith as a parameter and LPARM is Smith then Smith is not equal to smith and not records are selected.

SAS Employee
Posts: 1

Re: What is wrong in my macro code?

May want to try:

%let param=%upcase(&param);

data labtabs;

  merge data1 data2;

  by pt;

  if upcase(LPARM) = "&param";

*********FLUFF******

run;

Also, within macro everything is text, so you generally don't need and don't want to use quotes, which will lose their special meaning once they are pushed to the macro processor. Also, not necessary to initialize i.

%macro CreateLabTab(paramlist,headerlist);
   %put &=paramlist;
   %put &=headerlist;
   /*%let i=1;*/

   %do i = 1 %to %sysfunc(countw(&paramlist));
      %let param=%scan(&paramlist., &i,%bquote( ));
      %let header=%scan(&headerlist., &i,%bquote(,));
      %put &=i &=param &=header;
   %end;
%mend;

%let paramlist = ALK_PHOS_SER  AST_SGOT_SER;
%let headerlist=Alkaline phosphatase (U/L),ALT (mg/dL);

%CreateLabTab(&paramlist,%bquote(&headerlist));

Valued Guide
Posts: 3,208

Re: What is wrong in my macro code?

any reason for not using the by statement?  Base SAS(R) 9.4 Procedures Guide, Third Edition

As your datalabs dataset is empty check that step first (without the selection) before proceeding with the report.

---->-- ja karman --<-----
Occasional Contributor
Posts: 5

Re: What is wrong in my macro code?

A few things wrong here.

1 - you're changing the value of macvar i. This is set/automatically incremented by SAS as part of the %do ... %to... . So you don't need to initialise it to 1, SAS does it, but this won't have caused a problem. You must not change the value yourself. When you increment it at the end of the loop, SAS does it again as well - so you go in with 1, second time around with your and SAS' increments it goes in with value 3, not the 2 you're expecting. So you'll only process every other value in the parameter lists.

2 - labtabs empty - not clear what's happening here. First suspect is the IF statement. Comment it out and see what happens. Case (suggested above) is a good starting point. You may also need to left align the variable. It's also possible that the macro variable &paramlist used to supply &param is empty, we can't see from what you've posted. However if the variable lparm exists on both datasets and is empty in data2 or contains a value in data2 that doesn't correspond to &param, it'll always fail, as the righthand dataset value will overwrite the left hand dataset value. Another culprit could be the values in variable pt, especially if data1 and data2 aren't sorted by pt. 

Contributor
Posts: 24

Re: What is wrong in my macro code?

You use different tables in data step and  proc report.

You use quotes instead of quoting functions.

You dont use delimiters with the %scan and countw functions

You manipulate the &i variable in the loop.

You do not delete the labtabs table at the end of each loop

May be this code will solve the problem.

%macro CreateLabTab(paramlist,headerlist);

  /* Declaring of local used variables */

  %local i param header count Nobs;

  /* Quoting of Parameters */

  %let paramlist  = %BQuote(&paramlist.);

  %let headerlist = %BQuote(&headerlist.);

  /* Sorting the data into temporary tables */

  Proc sort data = data1 out = work._T_&sysmacroname.1; by pt; run;

  Proc sort data = data2 out = work._T_&sysmacroname.2; by pt; run;

  /* Counting the number of loops , defining the space as delimiter */

  %let count = %sysfunc(countw(&paramlist., %str( )));

  %do i = 1 %to &count.;

  /* Initialize the number of obs in the resulting dataset */

    %let Nobs   = 0;

    /* Splitting the parameterlists with delimiter and showing the results to the log */

    %let param  = %scan(&paramlist. , &i, %str( ));

    %let header = %scan(&headerlist., &i, %str(,));

    %put;

    %put %Str(Parameter  &i.);

    %put %str(  Param : &param.);

    %put %str(  Header: &header.);

    /* Numbering the tables (or creating a third temporary table and deleting at the end of the loop) */

    data labtabs&i.;

      retain nobs 0;

      merge _T_&sysmacroname.1 _T_&sysmacroname.2 end=done;

      by pt;

      /* Standardization of the texts with upcase, count the number of hits and output*/

      if Upcase(LPARM) = Upcase("&param") then do;

        Nobs + 1;

        *********FLUFF******;

        output;

      end;

      /* saving the number of obs in the resulting Dataset */

      if done then call symputx("Nobs",Nobs);

    run;

    /* Generate report */

    %if &Nobs. > 0 %then %do;

      proc report nowd data=labtabs&i. headline headskip split='/';

        column ('Patient' idvar) ("Title" groupnum) ("&header" time, (lvalue))  dummy;

        define idvar/ group order = data left '';

        define groupnum/group order = data center '';

        define time/across center '' order = data;

        define lvalue/ center '';

        define dummy/ noprint;

      run;

    %end; /* end of %if &Nobs. > 0 */

    %else %do;

      %put NOTE: Dataset Labtabs&i. has no data;

      %put NOTE: Do not generate report;

    %end; /* end of %else case from %if &Nobs. > 0 */

  %end;   /* end of %do i = 1 %to &count. */

  /* deleting the temporary tables */

  proc datasets nolist nodetails;

    delete _T_&sysmacroname.1 _T_&sysmacroname.2;

    run;

  quit;

%mend;

%let paramlist = ALK_PHOS_SER  AST_SGOT_SER;

%let headerlist=Alkaline phosphatase (U/L),ALT (mg/dL);

%CreateLabTab(&paramlist.,%bquote(&headerlist.));

Ask a Question
Discussion stats
  • 9 replies
  • 627 views
  • 0 likes
  • 7 in conversation