BookmarkSubscribeRSS Feed
JohnPura
Calcite | Level 5

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

9 REPLIES 9
jakarman
Barite | Level 11

remembers me of: Macro quoting made easy - SAS Users

---->-- ja karman --<-----
JohnPura
Calcite | Level 5

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

LinusH
Tourmaline | Level 20

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
ballardw
Super User

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.

mestran
SAS Employee

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));

jakarman
Barite | Level 11

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 --<-----
kevgermany
Calcite | Level 5

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. 

jh_ti_bw
Obsidian | Level 7

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.));

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 1606 views
  • 0 likes
  • 7 in conversation