- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Tags:
- sas
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
You could use proc nlmixed insider proc iml.
proc iml;
.........
submit ;
proc nlmixed;
......
endsubmit;
quit;
calling @Rick_SAS
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Then put an out= to create a dataset from the proc nlmixed and use that in your iml.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;