Hi,
I am working with a multiple imputed dataset and I want to make a frequency table of the responders. With the statement I use, I get frequency tables for every imputed dataset separately, but how do I combine these results in 1 final result using proc mi analyze?
proc freq data = test;
tables responders*intervention ;
BY _Imputation_;
RUN;
Thank you for the help.
Because Proc FREQ does not report a standard error for the frequency, you would not be able to combine the estimates in Proc MIANALYZE. Instead you must use Proc SURVEYFREQ. Below is an example.
/* Generate Data */
proc format;
value ResponseCode 1 = 'Very Unsatisfied'
2 = 'Unsatisfied'
3 = 'Neutral'
4 = 'Satisfied'
5 = 'Very Satisfied';
run;
proc format;
value UserCode 1 = 'New Customer'
0 = 'Renewal Customer';
run;
proc format;
value SchoolCode 1 = 'Middle School'
2 = 'High School';
run;
proc format;
value DeptCode 0 = 'Faculty'
1 = 'Admin/Guidance';
run;
data SIS_Survey;
format Response ResponseCode.;
format NewUser UserCode.;
format SchoolType SchoolCode.;
format Department DeptCode.;
do _imputation_=1 to 2;
drop j;
retain seed1 111;
retain seed2 222;
retain seed3 333;
State = 'GA';
NewUser = 1;
do School=1 to 71;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; end;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; end;
end;
NewUser = 0;
do School=72 to 134;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; end;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; end;
end;
State = 'NC';
NewUser = 1;
do School = 135 to 218;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; output;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; output;
end;
NewUser = 0;
do School = 219 to 274;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; end;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; output;
end;
State = 'SC';
NewUser = 1;
do School = 275 to 328;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; end;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; output;
end;
NewUser = 0;
do School = 329 to 370;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; end;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; output;
end;
end;
run;
title 'School Information System Survey';
/*Run SURVEYFREQ by _IMPUTATION_ assuming the MI step is already done*/
proc surveyfreq data=SIS_Survey;
by _imputation_;
tables Response*schooltype/wtfreq;
ods output CrossTabs=mi_ctab;
run;
proc print;
run;
/*Sort the data by the TABLES variables which is called RESPONSE here*/
proc sort data=mi_ctab;
by response schooltype _imputation_;
run;
/*Run MIANALYZE with STDERR option*/
proc mianalyze data=mi_ctab;
by response schooltype;*this would be the TABLES variable;
modeleffects wgtfreq;
stderr stdDev;
title 'Results of for Weighted Frequency';
run;
Because Proc FREQ does not report a standard error for the frequency, you would not be able to combine the estimates in Proc MIANALYZE. Instead you must use Proc SURVEYFREQ. Below is an example.
/* Generate Data */
proc format;
value ResponseCode 1 = 'Very Unsatisfied'
2 = 'Unsatisfied'
3 = 'Neutral'
4 = 'Satisfied'
5 = 'Very Satisfied';
run;
proc format;
value UserCode 1 = 'New Customer'
0 = 'Renewal Customer';
run;
proc format;
value SchoolCode 1 = 'Middle School'
2 = 'High School';
run;
proc format;
value DeptCode 0 = 'Faculty'
1 = 'Admin/Guidance';
run;
data SIS_Survey;
format Response ResponseCode.;
format NewUser UserCode.;
format SchoolType SchoolCode.;
format Department DeptCode.;
do _imputation_=1 to 2;
drop j;
retain seed1 111;
retain seed2 222;
retain seed3 333;
State = 'GA';
NewUser = 1;
do School=1 to 71;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; end;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; end;
end;
NewUser = 0;
do School=72 to 134;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; end;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; end;
end;
State = 'NC';
NewUser = 1;
do School = 135 to 218;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; output;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; output;
end;
NewUser = 0;
do School = 219 to 274;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; end;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; output;
end;
State = 'SC';
NewUser = 1;
do School = 275 to 328;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; end;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; output;
end;
NewUser = 0;
do School = 329 to 370;
call rantbl( seed1, .45, .55, SchoolType );
Department = 0;
call rannor( seed3, x );
SamplingWeight = 25 + x * 2;
do j=1 to 2;
if ( SchoolType = 1 ) then
call rantbl( seed2, .16, .21, .30, .24, .09, Response);
else
call rantbl( seed2, .18, .23, .30, .22, .07, Response);
output; end;
output;
Department = 1;
call rannor( seed3, x );
SamplingWeight = 15 + x * 1.5;
if ( SchoolType = 1 ) then
call rantbl( seed2, .10, .15, .33, .28, .14, Response );
else
call rantbl( seed2, .13, .20, .30, .26, .11, Response);
output; output;
end;
end;
run;
title 'School Information System Survey';
/*Run SURVEYFREQ by _IMPUTATION_ assuming the MI step is already done*/
proc surveyfreq data=SIS_Survey;
by _imputation_;
tables Response*schooltype/wtfreq;
ods output CrossTabs=mi_ctab;
run;
proc print;
run;
/*Sort the data by the TABLES variables which is called RESPONSE here*/
proc sort data=mi_ctab;
by response schooltype _imputation_;
run;
/*Run MIANALYZE with STDERR option*/
proc mianalyze data=mi_ctab;
by response schooltype;*this would be the TABLES variable;
modeleffects wgtfreq;
stderr stdDev;
title 'Results of for Weighted Frequency';
run;
Thank you for this reply, it worked!
Now I had another question. Is it possible to perform a chi-square test and have a p-value for the imputed frequency data (comparing responders to non responders )?
Best regards
Yes. You would have to combine the actual Chi-Square statistics from each of the tables. Dr. Paul Allison has a macro on his website that will compute the combined Chi-Square statistics.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.