Help using Base SAS procedures

Do loop

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 10
Accepted Solution

Do loop

Hello,

I'm using SAS 9.3.1 and I am trying to assign the values of a variable (demand) from a file (a) to a new set of variables using do loops. The problem is that the file 'a' has 5 observations and therefore after the first execution it reads all the data perfectly. But for the second round (i=2) it cannot perform the same task and start reading the file 'a' just like the previous iteration. It is like when a file is read once cannot be read for the second time. As the result, I don't have the desired outputs for the second run. Please note that the program executes without showing any error.   

I'm forwarding you the whole file in which you can find this specific part with all data example I'm using. 

I do appreciate your time helping me to find out the problem.

 

Best Regards,

Mina

 

do i=1 to 2;
_type_='GE';
_row_='Res_P'||put(i,1.);
_col_='_RHS_';
_coef_=0;
output;
_type_=' ';
do k=1 to 4;
_col_='Y'||put(i,1.)||put(k,1.);
_coef_=1.0;
output;
end;
do h=1 to 5;
set a;
_col_='Z'||put(i,1.)||put(h,1.);
_coef_=1.0;
output;
_col_='S'||put(i,1.)||put(h,1.);
_coef_=-demand;
output;

end;
end;

Attachment

Accepted Solutions
Solution
‎12-15-2016 12:11 PM
Super User
Posts: 10,552

Re: Do loop

You may want to consider using some of the concatenation functions. In stead of

 

_col_='Z'||put(i,1.)||put(h,1.);

 

could use

_col_ = cats('Z',i,h);

 

CATS removes leading and trailing blanks. The || put(var, format.) will often have either leading or trailing blanks..

View solution in original post


All Replies
Super User
Posts: 5,099

Re: Do loop

The solution is simple (I think!), but comes with a warning.  Change the SET statement to become:

 

set a point=h;

 

POINT= tells the software which observation to bring in, but allows for moving back to the beginning and starting over again.

 

The warning:  by doing this, you may create an infinite loop.  While you haven't posted the entire DATA step, so it's impossible to be certain, you will likely need to add a STOP statement at the bottom of the DATA step to make sure it ends.

Occasional Contributor
Posts: 10

Re: Do loop

 Thank you so much, this idea should work... I'm very new in SAS, sorry for asking basic questions... what value then I need to use to start from the beginning when it ends reading the file?

Super User
Posts: 5,099

Re: Do loop

The interior DO loop uses:

 

do h=1 to 5;

 

So this automatically starts from the beginning because it uses H to choose which observation to read:

 

set have point=H;

Occasional Contributor
Posts: 10

Re: Do loop

I do appreciate you. I added the point=H to the set statement as an option:

set a point=H;

But it seems like I got stuck in a loop... should I add/change something else? This way it doesn't work...

Super User
Posts: 5,099

Re: Do loop

Yes.  When using point=, there often is no ending to the DATA step.  You have to add your own ending by adding a STOP statement.  I thought I pointed this out in my original response, but it's probably a lot to absorb at one time.  Nothing like experience to ingrain the knowledge though.

Super User
Super User
Posts: 7,432

Re: Do loop

Hi,

 

Well, firstly the code you give is very confusing.  It is really not a good idea to call your variables _xyz_ as these types of things are reserved for SAS core functionality.  

Now looking at the output, it all seems a bit overcomplicated - there is lots being created here for no apparent reason or logic, therefore any work you do further on this data will be far harder.  I am presuming its for a report?  

Anyways, as the basis is demand, and you create a bunch of observations for each obs in demand, set that as your base loop:

data modified;
  set demand;
  _row_=cats("Res_P",put(customer,best.));
  _col_="_RHS_";
  _coef_=0;
  output;
  do i=10 to 14;
    _col_=cats("Y",put(i,best.));
    _coef_=1;
    output;
  end;
  do i=11 to 15;
    _col_=cats("Z",put(i,best));
    _coef_=...;
    output;
    _col_=cats("S",put(i,best.));
    _coef_=...;
    output;
  end;
run;

Here, instead of doing some creation, then later setting the data in a loop, I use the demand dataset and for each observation output a bunch of rows.  Seems simpler to me, but then as I say the whole structure and purpose of this output is a total mystery to my, or why you would want to do things in this manner?

Occasional Contributor
Posts: 10

Re: Do loop

Thank you so much. You are right, this structure is weird and I don't like it either, but I have to adhere to that to prepare my data for the proc lp (for SAS OR)... I cannot change the counter because I need to write it there... 

Solution
‎12-15-2016 12:11 PM
Super User
Posts: 10,552

Re: Do loop

You may want to consider using some of the concatenation functions. In stead of

 

_col_='Z'||put(i,1.)||put(h,1.);

 

could use

_col_ = cats('Z',i,h);

 

CATS removes leading and trailing blanks. The || put(var, format.) will often have either leading or trailing blanks..

Occasional Contributor
Posts: 10

Re: Do loop

Oh! thank you so much for giving me this point. This will be really helpful.

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 9 replies
  • 354 views
  • 4 likes
  • 4 in conversation