简体   繁体   中英

SAS using an iterating variable with a do loop

I have a sample data set, and I'm trying to create a new data set from each observation (record) with a do loop.

here's the sample code:

data tst;
input a b;
datalines;
1 2
2 3
;
run;

data ds1 ds2;
set tst 
/*point = point nobs = Nobs*/
;
do i=1 to 2;
    call symput("i",i);
    %put &=i;
    if _n_ then output ds&i.;
end;
run;

I'm confused why the &i. is not resolving correctly. It looks like in the log there's a lot of space preceeding it. I tried using the compress function on ds&i. and that's not working. I know I could use a macro and do this without call symput(), but I'm wondering what the issue with this is?

Ideal output:

DS1:
ab 1 2

DS2:
ab 2 3

This is a known behavior. Excerpt from the call symput manual:

Problem Trying to Reference a SYMPUT-Assigned Value Before It Is Available

One of the most common problems in using SYMPUT is trying to reference a macro variable value assigned by SYMPUT before that variable is created. The failure generally occurs because the statement referencing the macro variable compiles before execution of the CALL SYMPUT statement that assigns the variable's value. The most important fact to remember in using SYMPUT is that it assigns the value of the macro variable during program execution. Macro variable references resolve during the compilation of a step, a global statement used outside a step, or an SCL program. As a result:

You cannot use a macro variable reference to retrieve the value of a macro variable in the same program (or step) in which SYMPUT creates that macro variable and assigns it a value.

You must specify a step boundary statement to force the DATA step to execute before referencing a value in a global statement following the program (for example, a TITLE statement). The boundary could be a RUN statement or another DATA or PROC statement.

It happens cause macro variable can't be used in data step where it was initialized. So I think you should use macro(and fix if statement, in sample done like i think should be):

data tst;
input a b;
datalines;
1 2
2 3
;
run;

%macro output(); %macro d;%mend d;
   data ds1 ds2;
   set tst 
   /*point = point nobs = Nobs*/
   ;
   %do i=1 %to 2;
       if mod(_n_,&i)=0 then output ds&i.;
       /*if _n_=&i then output ds&i.;*/
   %end;
   run;
%mend output;

%output();

dataset tst:

+---+---+
| a | b |
+---+---+
| 1 | 2 |
| 2 | 3 |
+---+---+

dataset ds1:

+---+---+
| a | b |
+---+---+
| 1 | 2 |
+---+---+

dataset ds2:

+---+---+
| a | b |
+---+---+
| 2 | 3 |
+---+---+

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