BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Ujjawal
Quartz | Level 8

Hi Experts,

I am in the process of building a macro. The code is shown below.

I have concatenated macro variables with some prefix (sqrt_ for square roots etc). When i ask to print using %put, it is showing macro variable with concatenated text correctly. However, when i use it in PROC LOGISTIC, it returns " sqrt_ not found" error.

%let varName =%qscan(%sysfunc(compbl(&numvar)),&i,%str( ));

%let srtvar1 = sqrt_&varName.;

%put &varName. &srtvar1.;

options  symbolgen;

ODS OUTPUT EFFECTNOTINMODEL = Estimate&i.;

PROC LOGISTIC DATA = &output. DESC;

MODEL &depvar. = &varName. &srtvar1.

/ SELECTION = S MAXSTEP = 1 DETAILS;

RUN;

Detailed Code :

%macro test(input = ,depvar=, output=);

data _null_;

call symput ("library", put(upcase(substr("&input",1,index("&input",'.')-1)), $8.));

call symput ("datset", put(upcase(substr("&input",index("&input",'.')+1,length("&input"))), $32.));

run;

*Selecting numeric variables;

proc sql noprint;

select name into : numvar separated by " "

from dictionary.columns

where LIBNAME = "&library"

and MEMNAME = "PREDATA"

and type = 'num';

quit;

%let varn=%sysfunc(countw(&numvar%str( )));

     

*Run for all the numeric variables;

%DO i=1 %TO &varn;

*Selecting Variable one by one;

%let varName =%qscan(%sysfunc(compbl(&numvar)),&i,%str( ));

%let srtvar1 = sqrt_&varName.;

%let sqvar1  = sq_&varName.;

%let logvar1 = log_&varName.;

%let invvar1 = inv_&varName.;

%let cbvar1  = cb_&varName.;

%let cbrtvar1= cbrt_&varName.;

%put &varName. &srtvar1.;

options  symbolgen;

ODS OUTPUT EFFECTNOTINMODEL = Estimate&i.;

PROC LOGISTIC DATA = &output. DESC;

MODEL &depvar. = &varName. &srtvar1. &sqvar1. &logvar1. &invvar1. &cbvar1. &cbrtvar1.

/ SELECTION = S MAXSTEP = 1 DETAILS;

RUN;

options  nosymbolgen;

%mend;

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

I would suggest simplifying this line:

%let varName =%qscan(%sysfunc(compbl(&numvar)),&i,%str( ));

This would be sufficient, since blanks are the only delimiters that might be found in a list of normal variable names:

%let varName =%scan(&numvar,&i);

It's conceivable that the quoting character introduced by %QSCAN causes a problem.

If this doesn't work, you'll need to show your real code.  We know that a %DO statement with no matching %END is different than your actual code.

View solution in original post

5 REPLIES 5
Ron_MacroMaven
Lapis Lazuli | Level 10

examine the data structure of your input data and verify the presence of the variable names you are seeking

proc sql; describe table &data;

quit;

Ujjawal
Quartz | Level 8

Variables are in the file. Still it is throwing error -"Sqrt_ not found". If you look at error - It is not saying - "Sqrt_Height" not found.

Astounding
PROC Star

I would suggest simplifying this line:

%let varName =%qscan(%sysfunc(compbl(&numvar)),&i,%str( ));

This would be sufficient, since blanks are the only delimiters that might be found in a list of normal variable names:

%let varName =%scan(&numvar,&i);

It's conceivable that the quoting character introduced by %QSCAN causes a problem.

If this doesn't work, you'll need to show your real code.  We know that a %DO statement with no matching %END is different than your actual code.

Tom
Super User Tom
Super User

The value of macro variable SRTVAR1 is being treated as two tokens because of the macro quoting.

You should not need to use %QSCAN() since you are using the result as part of a variable name.

%let varName =%SCAN(%sysfunc(compbl(&numvar)),&i,%str( ));

%let srtvar1 = sqrt_&varName.;

%put &varName. &srtvar1.;

Unless ou are using validvarname=ANY option.  Then you need to use name literals to allow the name to include special characters.

%let varName =%QSCAN(%sysfunc(compbl(&numvar)),&i,%str( ));

%let srtvar1 = "sqrt_&varName."N;

%put &varName. &srtvar1.;

Ron_MacroMaven
Lapis Lazuli | Level 10

this comment is a side note

this code can be simplified

data _null_;

call symput ("library", put(upcase(substr("&input",1,index("&input",'.')-1)), $8.));

call symput ("datset", put(upcase(substr("&input",index("&input",'.')+1,length("&input"))), $32.));

run;

to this

%* deconstruct data into SAS naming conventions;

%let data = %lowcase(&data);

%if   %index(&data,.) %then %do;

      %*is.a two-level name libref.data_name;

      %let libname = %scan(&data,1,.);

      %let memname = %scan(&data,2,.);

      %end;

%else %do;

      %*is.a one-level-name;

      %let libname = work;

      %let memname = &data;

      %end;

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!

How to Concatenate Values

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.

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
  • 5 replies
  • 1214 views
  • 7 likes
  • 4 in conversation