Is there a way I can report odds ratio comparing 2 points for a GAM model?
proc gampl data=mydata;
class gender / param=ref;
model response(event='1') = gender spline(age) / dist=binary link=logit;
run;
For eg, is there a way, I can report OR at say age=65 to age=75? I know that R has an package, oddsratio specifically for GAM to get such odds ratios. How can we replicate something similar in SAS?
If I understood @StatDave 's code ,you can report OR at age=65 to age=75 .
a.k.a OR= odds(age=65)/odds(age=75)
data have;
set sashelp.heart(obs=1000 keep=status sex ageatstart rename=(ageatstart=age sex=gender));
run;
data test;
gender='Male';age=65;output;
gender='Male';age=75;output;
run;
data mydata;
set have test indsname=indsname;
dsn=indsname;
run;
proc gampl data=mydata;
class gender / param=ref;
id dsn;
model status= param(gender) spline(age) / dist=binary link=logit;
output out=out xbeta=logodds;
run;
proc transpose data=out(where=(dsn='WORK.TEST')) out=logodds;
run;
proc report data=logodds nowd split='*';
column col1 col2 or;
define col1/display 'log(odds) for age=65';
define col2/display 'log(odds) for age=75';
define or/computed 'OR=odds(age=65)/odds(age=75)';
compute or;
or=exp(col1-col2);
endcomp;
run;
NOTE: as @StatDave indicated the Male and Female have the same OR since model did not include interact effect “gender*age” . You can test it with the following data. Thanks Dave.
data test; /*gender='Male ';age=65;output;*/ /*gender='Male ';age=75;output;*/ gender='Female';age=65;output; gender='Female';age=75;output; run;
You cannot write contrasts in PROC GAM or PROC GAMPL. Is there a workaround this? This is easily achieved in R for GAM models.
You can fit a Generalized Additive logistic model to a binary response and obtain odds ratio estimates using the EFFECT statement in PROC LOGISTIC. The EFFECT statement creates the spline effect that you can use in the model. See the example in this note. In addition to the ODDSRATIO statement, you'll use the UNITS statement to specify the interval size that you want. For example
proc logistic data=mydata;
effect spla=spline(age/naturalcubic basis=tpf(noint));
class gender / param=ref;
model response(event='1') = gender spla;
oddsratio age / at(age=65);
units age=10;
run;
This is not a GAM model. I need to fit a GAM and not a GLM model.
GAM uses penalized likelihood with a penalty term for smoothing which is missing in GLM. For the outcomes we deal with, GAM gives the best fit for such types of data. I am aware of how it is done in SAS and getting contrasts for the spline effects but at this point what I am looking for is a solution using PROC GAM.
If you have to use PROC GAMPL then you could compute the odds ratio from the predicted log odds values, which are available with the XBETA= option in the OUTPUT statement when fitting a logistic model. For example, these statements compute the odds ratio for a one unit (year) increase in age from 65 to 66 in the Neuralgia data as seen in an example in the PROC LOGISTIC documentation. Since a spline is used, the odds ratio estimate will differ depending at which age it is computed. The values in the DATA step are the estimated log odds for a 66 year old male and a 65 year old male. The exponentiated difference in the log odds is the odds ratio for a unit (year) increase in age.
proc gampl data=neuralgia;
class sex; id sex age;
model pain(event='No') = param(sex) spline(age) / dist=binomial;
output out=outg xbeta=logodds;
run;
data _null_; or=exp(0.4048343234-0.5202755281); put or=; run;
If I understood @StatDave 's code ,you can report OR at age=65 to age=75 .
a.k.a OR= odds(age=65)/odds(age=75)
data have;
set sashelp.heart(obs=1000 keep=status sex ageatstart rename=(ageatstart=age sex=gender));
run;
data test;
gender='Male';age=65;output;
gender='Male';age=75;output;
run;
data mydata;
set have test indsname=indsname;
dsn=indsname;
run;
proc gampl data=mydata;
class gender / param=ref;
id dsn;
model status= param(gender) spline(age) / dist=binary link=logit;
output out=out xbeta=logodds;
run;
proc transpose data=out(where=(dsn='WORK.TEST')) out=logodds;
run;
proc report data=logodds nowd split='*';
column col1 col2 or;
define col1/display 'log(odds) for age=65';
define col2/display 'log(odds) for age=75';
define or/computed 'OR=odds(age=65)/odds(age=75)';
compute or;
or=exp(col1-col2);
endcomp;
run;
NOTE: as @StatDave indicated the Male and Female have the same OR since model did not include interact effect “gender*age” . You can test it with the following data. Thanks Dave.
data test; /*gender='Male ';age=65;output;*/ /*gender='Male ';age=75;output;*/ gender='Female';age=65;output; gender='Female';age=75;output; run;
Since gender does not interact with the age spline, the odds ratio estimate applies to both genders.
Thank you @Ksharp !!! This is awesome and an interesting way of getting the ORs.
How would you write it if spline(age) and sex were interacting? Basically if I had to use PROC LOGISTIC, can I use the same code to get effect for Age 45 vs 55 for males? Also if I had to get the ORs for say 10 different time points, 45,47,48..etc vs 55, is there a way to write a macro in the Proc report to repeat the calculations for many time points?
I wonder if I should start a new thread.
If I use ESTIMATE then I do not get the same answers. I am not doing something right.
proc logistic data=mydata;
class gender / param=ref;
effect splage=spline(age/ basis=tpf knotmethod=equal(3));
id dsn;
model status= gender splage gender*splage ;
estimate 'For M: 45 vs 50(ref)' gender 2 splage[1,45][-1,50] gender*splage [1,2 45] [-1,2 50] / E EXP CL;
output out=out xbeta=logodds;
run;
proc transpose data=out(where=(dsn='WORK.TEST')) out=logodds;
run;
proc report data=logodds nowd split='*';
column col1 col2 or;
define col1/display 'log(odds) for age=45';
define col2/display 'log(odds) for age=50';
define or/computed 'OR=odds(age=45)/odds(age=50)';
compute or;
or=exp(col1-col2);
endcomp;
run;
If I am using @StatDave 's code, I could get the same OR.
Check this:
1) Main Effect --> Same OR
data have;
set sashelp.heart(obs=1000 keep=status sex ageatstart rename=(ageatstart=age sex=gender));
run;
data test;
gender='Male';age=65;output;
gender='Male';age=75;output;
run;
data mydata;
set have test indsname=indsname;
dsn=indsname;
run;
proc logistic data=mydata;
class gender / param=ref;
effect spla=spline(age/naturalcubic basis=tpf(noint));
model status= gender spla ;
oddsratio age / at(age=65);
units age=10;
/* estimate 'For M: 45 vs 50(ref)' gender 2 splage[1,45][-1,50] gender*splage [1,2 45] [-1,2 50] / E EXP CL;*/
output out=out xbeta=logodds;
run;
proc transpose data=out(where=(dsn='WORK.TEST')) out=logodds;
var logodds;
run;
proc report data=logodds nowd split='*';
column col1 col2 or;
define col1/display 'log(odds) for age=65';
define col2/display 'log(odds) for age=75';
define or/computed 'when gender="Male"*OR=odds(age=75)/odds(age=65)';
compute or;
or=exp(col2-col1);
endcomp;
run;
2) Interact Effect --> Also same OR
proc logistic data=mydata;
class gender / param=ref;
effect spla=spline(age/naturalcubic basis=tpf(noint));
model status= gender spla gender*spla;
oddsratio age / at(age=65);
units age=10;
/* estimate 'For M: 45 vs 50(ref)' gender 2 splage[1,45][-1,50] gender*splage [1,2 45] [-1,2 50] / E EXP CL;*/
output out=out xbeta=logodds;
run;
Nearly 200 sessions are now available on demand with the SAS Innovate Digital Pass.
Explore Now →ANOVA, or Analysis Of Variance, is used to compare the averages or means of two or more populations to better understand how they differ. Watch this tutorial for more.
Find more tutorials on the SAS Users YouTube channel.