Reputation: 177
I have a macro variable
%let dates = (200101, 200102, 200103);
How do I create this list?
var_out = pop_200101 pop_200102 pop_200103
I can loop through and select the date:
%do i=1 %to %sysfunc(countw(%superq(dates),%str(,)));
%let this_date = %scan(&dates., &i.);
and I can concatenate:
catt(pop,_&this_date.);
but I don't know how to actually put this into a list.
Edit: additional info
I have some data
data example;
input Q40_ret_200101 Q40_ret_200102 Q40_ret_200103;
datalines;
4 6 .
. 8 9
3 7 4
2 3 .
;
run;
I am trying to do
proc summary
data = example nway;
var Q40_ret_200101 Q40_ret_200102 Q40_ret_200103;
output out = count
N = pop_200101 pop_200102 pop_200103;
run;
However in reality my dataset is much larger and it is no feasible for me to write in all the variables. I have managed to get a list of my variable names for the var statement.
PROC CONTENTS
DATA = example
OUT = VAR_NAMES (KEEP = NAME) NOPRINT;
RUN;
/*read in variable names and use substr to test if starts with q40_ret*/
DATA PARSE;
SET VAR_NAMES;
WHERE (SUBSTR(NAME, 1,8) = 'Q40_ret_');
RUN;
DATA _NULL_;
FILE 'C:';
SET PARSE END = FINIS;
IF _N_ = 1 THEN PUT '%LET VAR_LIST = ';
PUT NAME;
IF FINIS THEN DO;
CALL SYMPUT('NUM' , COMPRESS(_N_));
PUT ';';
PUT 'RUN;';
END;
RUN;
/*Next, the file ‘BUILD‘ is read back into the SAS program using a %INCLUDE statement.*/
%include 'C:\BUILD';
So far my proc summary statement looks like this:
proc summary
data = example nway;
var &var_list;
output out = pop (drop = _TYPE_ _FREQ_)
N =;
run;
But I still need to generate and state the output variable names
Upvotes: 0
Views: 2647
Reputation: 27498
A doSubL
side session program can compute and populate the value for the var_out
macro symbol. The benefit of using %sysfunc(doSubL(
is that the side program does not create a step boundary in the invoking session.
Example:
The construct of the dates
macro variable value can also be used as an array initialization in the doSubL
code.
%let dates = (200101, 200102, 200103);
%let rc=%sysfunc(dosubl(
data _null_;
array dates (%sysfunc(countw(&dates))) &dates;
do index = 1 to dim(dates);
length list $200;
list = catx(' ', list, cats('pop_',dates(index)));
end;
call symput('var_out',trim(list));
run;
));
%put &=var_out;
---------- LOG ----------
VAR_OUT=pop_200101 pop_200102 pop_200103
Upvotes: 3
Reputation: 21264
If you can change your list slightly by removing the parentheses and commas this is quite easy. Alternatively you could use COMPRESS() to remove the parenthesis and commas and then use this solution.
%macro prefix(prefix,list);
%local i bit;
%let i=1;
%let bit=%sysfunc(scanq(&list,&i,%str( )));
%do %while(%length(&bit));
&prefix.&bit
%let i=%eval(&i+1);
%let bit=%sysfunc(scanq(&list,&i,%str( )));
%end;
%mend prefix;
%let dates = (200101, 200102, 200103);
%let want = %prefix(pop_, 200101 200102 200103);
%put &want;
Via: http://www.datasavantconsulting.com/roland/Spectre/utilmacros/prefix.sas
Upvotes: 1