简体   繁体   中英

Create list by appending in do loop SAS

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM