it says:
WARNING: Apparent symbolic reference PID1 not resolved.
WARNING: Apparent symbolic reference PID4 not resolved.
data t;
input pid;
cards;
10
31
31
2
12
12
;
options mprint;
%macro dyn_var_nm(in_var_nm=,ds=,out_var_nm=);
proc sql;
select count(distinct &in_var_nm) into :nobs from &ds;
/*%let nobs = &nobs;*/
select distinct &in_var_nm into :&&out_var_nm.1-:&&out_var_nm.%left(&nobs) from &ds;
quit;
%mend;
%dyn_var_nm(ds=t,in_var_nm=pid,out_var_nm=pid);
%put &pid1 &pid4;
My error. A list apparently can't be used in assigning the global variables. However, the following appears to work without error:
%macro dyn_var_nm(in_var_nm=,ds=,out_var_nm=);
proc sql;
select count(distinct &in_var_nm) into :nobs from &ds;
/*%let nobs = &nobs;*/
%do i=1 %to %left(&nobs);
%global &&out_var_nm.&i.;
%end;
select distinct &in_var_nm into :&&out_var_nm.1-:&&out_var_nm.%left(&nobs) from &ds;
quit;
%mend;
%dyn_var_nm(ds=t,in_var_nm=pid,out_var_nm=pid);
%put &pid1 &pid4;
They are being created, but only locally. Not sure how you want to use them but, if it is outside of the macro, you could define them as being global. e.g.:
data t;
input pid;
cards;
10
31
31
2
12
12
;
options mprint;
%macro dyn_var_nm(in_var_nm=,ds=,out_var_nm=);
proc sql;
select count(distinct &in_var_nm) into :nobs from &ds;
/*%let nobs = &nobs;*/
%global &&out_var_nm.1-&&out_var_nm.%left(&nobs);
select distinct &in_var_nm into :&&out_var_nm.1-:&&out_var_nm.%left(&nobs) from &ds;
quit;
%mend;
%dyn_var_nm(ds=t,in_var_nm=pid,out_var_nm=pid);
%put &pid1 &pid4;
%global &&out_var_nm.1 - &&out_var_nm.%left(&nobs);
ERROR: Invalid symbolic variable name -.
how do I solve this?
My error. A list apparently can't be used in assigning the global variables. However, the following appears to work without error:
%macro dyn_var_nm(in_var_nm=,ds=,out_var_nm=);
proc sql;
select count(distinct &in_var_nm) into :nobs from &ds;
/*%let nobs = &nobs;*/
%do i=1 %to %left(&nobs);
%global &&out_var_nm.&i.;
%end;
select distinct &in_var_nm into :&&out_var_nm.1-:&&out_var_nm.%left(&nobs) from &ds;
quit;
%mend;
%dyn_var_nm(ds=t,in_var_nm=pid,out_var_nm=pid);
%put &pid1 &pid4;
Great, it works now.
If you are willing to call it using %UNQUOTE() then you could code it so that the generated code runs in the calling environment. Then you could use it inside of another macro without forcing macro variables into the GLOBAL macro scope. Also this way you do not need to run the query twice just to count how many distinct values there will be.
data t;
input pid @@;
cards;
10 31 31 2 12 12
;
%macro dyn_var_nm(in_var_nm=,ds=,out_var_nm=);
%quote(proc sql noprint;)
select distinct &in_var_nm into :&&out_var_nm.1 - :&&out_var_nm.100000 from &ds
order by &in_var_nm
%quote(;quit;)
%mend;
%unquote(%dyn_var_nm(ds=t,in_var_nm=pid,out_var_nm=pid) );
%put PID1=&pid1 SQLOBS=&sqlobs PID&sqlobs=&&PID&sqlobs ;
PID1=2 SQLOBS=4 PID4=31
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.