Hi there,
I am using proc surveyreg to generate lsmeans of a continuous outcome across sex groups.
I would like both absolute difference and relative difference in means with corresponding 95%CIs, however the proc surveyreg procedure (which I MUST use as I have survey data) only generates absolute mean differences (meansex1 - meansex2), and will not give relative measures (meansex1/meansex2). I am wondering if this is a limitation of SAS and this procedure or if I am missing something?
I posted a sample of my code below, where I have tried lsmeans, estimate and lsmestimate.
proc surveyreg data=final varmethod=brr;
class sex;
model percent = sex/ clparm solution;
lsmeans sex/ cl diff e;
estimate "sex" sex -1 1 / cl;
lsmestimate sex -1 1/ cl;
weight wt;
repweights rep1-rep500;
run;
Thanks in advance!
The standard error and a large sample confidence interval for the ratio can be obtained either by the delta method or using Fieller's theorem. This note discusses and illustrates how these methods can be applied in a bioassay situation. You can modify your SURVEYREG code and use the NLEST macro to implement the delta method as shown in the following code. The NLEST macro can be directly called if you are using the current release, SAS 9.4 TS1M6. Otherwise, it can be downloaded from the link above.
proc surveyreg data=final varmethod=brr;
class sex;
model percent = sex/ clparm solution;
store out=sreg;
lsmeans sex / cov;
ods output lsmeans=lsm;
run;
%NLEst(instore=sreg, label=Mean Ratio, f=b_p1/b_p2, df=1e8)
A confidence interval for the ratio can also be obtained from Fieller's theorem and is computed by the code below
%macro Fieller(out=RatioCI, num=, den=, label=Ratio, alpha=.05);
proc iml;
use lsm;
read all var {Estimate} into beta;
read all var {Cov1 Cov2} into cov;
k={ &num }; h={ &den };
ratio=(k*beta) / (h*beta);
tsq=probit(1-&alpha/2)**2;
a=(h*beta)**2-(tsq)*(h*cov*h`);
b=2*(tsq*(k*cov*h`)-(k*beta)*(h*beta));
c=(k*beta)**2 -(tsq)*(k*cov*k`);
disc=((b**2)-4*a*c);
if (disc<=0 | a<=0) then do;
print "ERROR: confidence interval can't be computed";
stop;
end;
sroot=sqrt(disc);
l_b=((-b)-sroot)/(2*a);
u_b=((-b)+sroot)/(2*a);
estlims=ratio||l_b||u_b;
lname={"Estimate", "LCL", "UCL"};
create &out from estlims[colname=lname];
append from estlims;
quit;
data &out;
set &out;
Ratio="&label";
run;
proc print data=&out;
id Ratio;
run;
%mend;
%Fieller(num=1 0, den=0 1, label=Ratio)
Getting relative differences is easy, standard errors of the relative differences not so much. To get the relative values, use ODS OUTPUT to get the lsmeans into a data set that you can process thru a DATA step to get the relative differences. Getting the standard errors would probably involve using the delta method to approximate the variance of a ratio and then converting the variance to a standard error. There should be code somewhere on the interwebs that does this.
SteveDenham
The standard error and a large sample confidence interval for the ratio can be obtained either by the delta method or using Fieller's theorem. This note discusses and illustrates how these methods can be applied in a bioassay situation. You can modify your SURVEYREG code and use the NLEST macro to implement the delta method as shown in the following code. The NLEST macro can be directly called if you are using the current release, SAS 9.4 TS1M6. Otherwise, it can be downloaded from the link above.
proc surveyreg data=final varmethod=brr;
class sex;
model percent = sex/ clparm solution;
store out=sreg;
lsmeans sex / cov;
ods output lsmeans=lsm;
run;
%NLEst(instore=sreg, label=Mean Ratio, f=b_p1/b_p2, df=1e8)
A confidence interval for the ratio can also be obtained from Fieller's theorem and is computed by the code below
%macro Fieller(out=RatioCI, num=, den=, label=Ratio, alpha=.05);
proc iml;
use lsm;
read all var {Estimate} into beta;
read all var {Cov1 Cov2} into cov;
k={ &num }; h={ &den };
ratio=(k*beta) / (h*beta);
tsq=probit(1-&alpha/2)**2;
a=(h*beta)**2-(tsq)*(h*cov*h`);
b=2*(tsq*(k*cov*h`)-(k*beta)*(h*beta));
c=(k*beta)**2 -(tsq)*(k*cov*k`);
disc=((b**2)-4*a*c);
if (disc<=0 | a<=0) then do;
print "ERROR: confidence interval can't be computed";
stop;
end;
sroot=sqrt(disc);
l_b=((-b)-sroot)/(2*a);
u_b=((-b)+sroot)/(2*a);
estlims=ratio||l_b||u_b;
lname={"Estimate", "LCL", "UCL"};
create &out from estlims[colname=lname];
append from estlims;
quit;
data &out;
set &out;
Ratio="&label";
run;
proc print data=&out;
id Ratio;
run;
%mend;
%Fieller(num=1 0, den=0 1, label=Ratio)
@StatDave - That was the macro I remember seeing at some point. Thanks for getting it up here.
SteveDenham
Thank you for providing insight to this issue! Very much appreciated:)
Thank you so much for providing this solution!
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
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.