Jonsi Billups
Jonsi Billups

Reputation: 153

Infinite Loop while using Do while in SAS

I am very new but keen to learn SAS coding.I have 2 data sets a and b namely dt1 and dt2 which consist of columns a for dt1 and b and c for dt2:

a      b      c
2014   2008   2
       2009   3
       2014   4 
       2015   5

I am trying to get the nth row of the c column when the element which is at nth row of b column is equal to a(1) Here it is c=4; I wrote a code below.

DATA dt1;
   set dt1;
data dt2;
   set dt2;
   i=1;
   do while (b ne a);
      i=i+1;
   end;
   call symput('ROW_NUMBER',i);
run;

proc print data = dt2(keep = c obs = &ROW_NUMBER firstobs = &ROW_NUMBER);
run;

but this code enters in an infinite loop and I could not find any solution for this. I appreciate if you help solve this issue. Thanks

Upvotes: 0

Views: 645

Answers (3)

Joe
Joe

Reputation: 63424

This is a simple MERGE. You just need to rename the variables to match. This assumes they're both sorted by the value (a/b). You can then set the macro variable in that data step or do whatever you want.

data want;
  merge dt1(in=_a rename=a=b) dt2(in=_b);
  by b;
  if _a and _b;
  call symput("ROW_NUMBER",c);
run;

Upvotes: 2

Shenglin Chen
Shenglin Chen

Reputation: 4554

If you want to define macro variables:

data _null_;
set dt2;
if _n_=1 then set dt1;
if a=b then do;
call symput('c_val',c); 
call symput('row_num',_n_);
end;
run;

%put &row_num &c_val;

Upvotes: 0

DWal
DWal

Reputation: 2762

I think you should learn the basic syntax of the data step before trying to use macro variables. A lot of what you're doing makes little sense. Here is an explanation of how the data step works. You will do yourself a huge favor if you study that.

Here's how to do an inner join in proc sql, which seems to be more in line with your goal here. This simply selects the values of c where dt1.a is equal to dt2.b:

proc sql;
select c
from dt1 inner join dt2 on dt1.a = dt2.b;
quit;

If you were to use a data step, you'd do something like this the following.

data out(keep=c);
  set dt1;
  do until (a=b or eof);
    set dt2 end=eof;
    if a=b then output;
  end;
run;
proc print data=out noobs;
run;

Use the end= option to create temporary variable eof which allows you to end the loop after the last row of dt2 is read.

Upvotes: 2

Related Questions