Help using Base SAS procedures

Can I use a proc step within another proc step

Accepted Solution Solved
Reply
Contributor
Posts: 20
Accepted Solution

Can I use a proc step within another proc step

I am writing a Proc nlmixed code and for my likelihood function I want to used some values generated from a proc iml procedure. So I am wondering if there is a way of using proc iml inside a proc nlmixed code.
I have read from support sas and I see I am being advised to use proc fcmp......Could someone give me an example if possible.

proc nlmixed data = xxx;
parms b0=0 b1=0;
mu = exp(b0 + b1*Age);
ll = log(((mu**y)*exp(-mu))/gamma(y+1));
model y~ general(ll);
run;

proc iml;
v = {5,6,7,8,9,10,11,12,13,14};
z = j(10,1,.);
do i = 1 to 6;
z[i] = ((v[i]-5)/5)*((mu**v[i])*exp(-mu))/gamma(v[i]+1);
end;
ll=log(sum(z));
quit;

The idea is to use mu from the first proc step inside the second proc step but the ll from both steps should be inside nlmixed

Accepted Solutions
Solution
‎01-11-2018 03:37 PM
SAS Super FREQ
Posts: 4,247

Re: Can I use a proc step within another proc step

Your 'proc iml' part does not contain any matrix operations, so you can implement it by using the programming statements that are supported by PROC NLMIXED. You can use the ARRAY statement to define the v array. The PROC NLMIXED syntax also supports a DO loop. Within a DO loop, you can accumulate the sum of z. You do not need z to be an array in order to compute sum(z).It might look something like this (untested)

 


proc nlmixed data = Work.final ;
  array v[10];
  do i = 1 to 10;
     v[i] = i + 4;
   end;
  parms b0=0 b1=0;
  mu = exp(b0 + b1*Age);
  if SMD650 ~= 10 then
  ll = log(((mu**SMD650)*exp(-mu))/gamma(SMD650+1));
  else do;
     sum = 0;
     do i = 1 to 6;
      sum = sum + ((v[i]-5)/5)*((mu**v[i])*exp(-mu))/gamma(v[i]+1);
     end;
     do i = 7 to 10;
      sum = sum + ((v[i]-4)/4)*((mu**v[i])*exp(-mu))/gamma(v[i]+1);
     end;
     ll=log(sum);
  end;
  
  model SMD650 ~ general(ll);
run;	

 

 

View solution in original post


All Replies
Super User
Super User
Posts: 9,599

Re: Can I use a proc step within another proc step

No, its not possible.  From the proc iml you would save the output data;

https://blogs.sas.com/content/iml/2011/04/18/writing-data-from-a-matrix-to-a-sas-data-set.html

 

You would then use this output data, or merge it with other data and feed that into your proc mixed.

Super User
Posts: 10,787

Re: Can I use a proc step within another proc step

You could use proc nlmixed insider proc iml.

 

proc iml;

.........

submit ;

proc nlmixed;

......

endsubmit;

 

quit;

 

calling @Rick_SAS

Contributor
Posts: 20

Re: Can I use a proc step within another proc step

Its the other way round. proc iml inside proc nlmixed
Contributor
Posts: 20

Re: Can I use a proc step within another proc step

@RW9 executing proc iml alone is not possible because it uses some data from proc nlmixed.....i.e. mu from the above code.
Super User
Super User
Posts: 9,599

Re: Can I use a proc step within another proc step

Then put an out= to create a dataset from the proc nlmixed and use that in your iml.

Contributor
Posts: 20

Re: Can I use a proc step within another proc step

This is what I have

 

 

proc nlmixed data = Work.final ;
  parms b0=0 b1=0;
  mu = exp(b0 + b1*Age);
  if SMD650 ~= 10 then
  ll = log(((mu**SMD650)*exp(-mu))/gamma(SMD650+1));
  else
  proc iml;
  v = {5,6,7,8,9,10,11,12,13,14};
  z = j(10,1,.);
  do i = 1 to 6;
   z[i] = ((v[i]-5)/5)*((mu**v[i])*exp(-mu))/gamma(v[i]+1);
  end;
  do i = 7 to 10;
   z[i] = ((v[i]-4)/4)*((mu**v[i])*exp(-mu))/gamma(v[i]+1);
  end;
  ll=log(sum(z));
  
  model SMD650 ~ general(ll);
run;	

 

In other words the second last line (model SND50...) is part of the proc nlmixed, the if statement is also part of proc nlmixed. but the else part will have to go through the proc iml. So they are intertwined in that I can not create out= because the proc nlmixed will not be complete without proc iml.

Solution
‎01-11-2018 03:37 PM
SAS Super FREQ
Posts: 4,247

Re: Can I use a proc step within another proc step

Your 'proc iml' part does not contain any matrix operations, so you can implement it by using the programming statements that are supported by PROC NLMIXED. You can use the ARRAY statement to define the v array. The PROC NLMIXED syntax also supports a DO loop. Within a DO loop, you can accumulate the sum of z. You do not need z to be an array in order to compute sum(z).It might look something like this (untested)

 


proc nlmixed data = Work.final ;
  array v[10];
  do i = 1 to 10;
     v[i] = i + 4;
   end;
  parms b0=0 b1=0;
  mu = exp(b0 + b1*Age);
  if SMD650 ~= 10 then
  ll = log(((mu**SMD650)*exp(-mu))/gamma(SMD650+1));
  else do;
     sum = 0;
     do i = 1 to 6;
      sum = sum + ((v[i]-5)/5)*((mu**v[i])*exp(-mu))/gamma(v[i]+1);
     end;
     do i = 7 to 10;
      sum = sum + ((v[i]-4)/4)*((mu**v[i])*exp(-mu))/gamma(v[i]+1);
     end;
     ll=log(sum);
  end;
  
  model SMD650 ~ general(ll);
run;	

 

 

Contributor
Posts: 20

Re: Can I use a proc step within another proc step

Thanks a lot! this works perfectly but I can not figure out how I would add another else statement;  I mean if I have the following; How would I rearrange the commented section, with an inclusion array variable n.

 

proc nlmixed data = Work.final ;
  array v[10];
  do i = 1 to 10;
     v[i] = i + 4;
   end;
  parms b0=0 b1=0;
  mu = exp(b0 + b1*Age);
  if SMD650 ~= 10 and SMD650 ~=20 then
  ll = log(((mu**SMD650)*exp(-mu))/gamma(SMD650+1));


/**********
else if SMD650= 20 then
p=0;
  do n = 15 to 20;
      p = p+((n[i]-15)/5)*((mu**n[i])*exp(-mu))/gamma(n[i]+1);
  end;
  do n= 21 to 24;
      p = p+((24-n[i])/4)*((mu**n[i])*exp(-mu))/gamma(n[i]+1);
  end;
ll=log(p)
*********/

else do; sum = 0; do i = 1 to 6; sum = sum + ((v[i]-5)/5)*((mu**v[i])*exp(-mu))/gamma(v[i]+1); end; do i = 7 to 10; sum = sum + ((v[i]-4)/4)*((mu**v[i])*exp(-mu))/gamma(v[i]+1); end; ll=log(sum); end; model SMD650 ~ general(ll); run;

 

SAS Super FREQ
Posts: 4,247

Re: Can I use a proc step within another proc step

[ Edited ]

You must use a DO/END block with the IF-THEN/ELSE statement if you want the body of the IF/THEN to contain more than one statement. Notice how I used DO/END in my example. In your example:

 

else if SMD650= 20 then DO;
   p=0; 
   /* put more statements here */
END;
else  DO;
   /* put more statements here */
END; 
☑ This topic is solved.

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

Discussion stats
  • 9 replies
  • 310 views
  • 2 likes
  • 4 in conversation