简体   繁体   中英

sas datastep loop to calculate new rows of data

I have the below requirement and wondering if this can be implemented in simple datastep:

will be starting with a simple dataset with two variable

    input:  
    x   y   
    1   0

    
        
logic:      

x       y           z
1       0           x+y
prev z  prev y +1   x+y
prev z  prev y +1   x+y
        
output:     

    x   y   z
    1   0   1
    1   1   2
    2   2   4
    4   3   7
    7   4   11

Just output the computed rows one-by-one within a do-while loop.

data have;
     input x y;
     cards;
1 0
;run;

data want(drop=i);
    set have;
    z = x + y;
    output;
    i = 2;  /*next row*/
    do while (i <= 5);  /* put the total number of rows here */
        x = z;
        y = y + 1;
        z = x + y;
        output;
        i = i + 1;
    end;
run;

Result

proc print data=want;
run;

Obs x   y   z
1   1   0   1
2   1   1   2
3   2   2   4
4   4   3   7
5   7   4   11

Macro version:

%macro gen(have, want, n_rows);
    data &want(drop=i);
        set &have;
        z = x + y;
        output;
        i = 2;
        do while (i <= &n_rows);
            x = z;
            y = y + 1;
            z = x + y;
            output;
            i = i + 1;
        end;
    run;
%mend gen;

/* execute */
%gen(have, want, 5)

Ok. I decided to do some research to try to answer your question. And I found out that you (probably) did the same question in a sas forum (link here).

As any interested user may see, the question was answered in a very elegant way there (by Mr. Reinhard - credits to him).

While I was pasting Reinhard answer here, I saw that @Bill Huang came with an original answer his own. So probably you should accept his answer. Anyway, Reinhard answer was really cool and elegant, so I thought it might worth to have it registerd here. Mainly for other users, because it is such an easy way of creating additional interative rows in SAS:

data have;
x=1; y=0;
run;

data want;
set have;
do y=y to 4;
  z=x+y;
  output;
  x=z;
end;

@LuizZ's do y=y to 4 version presumes the first row has y=0 . If that is not the case try

data have;
  x=1; y=0;
run;

%let iterations = 4;

data want;
  set have;
  do y = y to y+&iterations;
    z = x + y;
    output;
    x = z;
  end;
run;

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