Hi everyone,
I have a 5x3 table, as shown below (letters and numbers are not my actual variable names, my variables are categorical but not ordinal). I have conducted a Fisher's exact test with Monte Carlo estimation and it is significant, but I was wondering if it's possible to apply post hoc z test of proportions with a Bonferroni adjustment? I have not been able to find an answer online/any example of SAS code online for this. Any help is appreciated!
TABLE:
A | B | C | D | E | |
1 | |||||
2 | |||||
3 |
Anytime you do something like this, you need to run the procedure once with your data to see exactly what tables are produced, which you want to work with, and exactly what its name is. Since these tables are larger than 2x2, you get a FisherExact table and a separate Monte Carlo table named FisherExactMC. Each has a p-value variable. If you save both of those tables with ODS OUTPUT, you will see that neither of them has a p-value variable called "XP2_FISH". That is the name of the variable in the FisherExact table if the table being analyzed is a 2x2 table. Depending on which p-value you want to use, this code does them both, using the correct variable names found by examining the tables that were produced for your data.
ODS OUTPUT fishersexact(PERSIST)=fisher(WHERE=(name1="P_TABLE"))
fishersexactmc(PERSIST)=fishmc(WHERE=(name1="MCP_FISH"));
PROC FREQ DATA= table1;
WHERE platform in (1,2);
TABLES platform*account_type;
exact fisher/mc;
RUN;
PROC FREQ DATA= table1;
WHERE platform in (1,3);
TABLES platform*account_type;
exact fisher/mc;
RUN;
PROC FREQ DATA= table1;
WHERE platform in (2,3);
TABLES platform*account_type;
exact fisher/mc;
RUN;
ODS OUTPUT CLEAR;
proc multtest inpvalues(nvalue1)=fisher bon;
run;
proc multtest inpvalues(nvalue1)=fishmc bon;
run;
You can use PROC MULTTEST as illustrated in this note. Many multiple testing adjustments are available, with some that are less conservative than the Bonferroni.
Thank you! I've modified some of the code included in the link you provided but I'm stuck on how to make this work for a Fisher's test.
ODS OUTPUT fishersexact(PERSIST)=fisher(WHERE=(name1="XP2_FISH") rename=(nvalue1=raw_p));
PROC FREQ DATA= winter_t1;
WHERE platform in ('Facebook', 'Twitter');
TABLES platform*account_type;
exact fisher/mc;
RUN;
PROC FREQ DATA= winter_t1;
WHERE platform in ('Facebook', 'Instagram');
TABLES platform*account_type;
exact fisher/mc;
RUN;
PROC FREQ DATA= winter_t1;
WHERE platform in ('Twitter', 'Instagram');
TABLES platform*account_type;
exact fisher/mc;
RUN;
ODS OUTPUT CLEAR;
proc print noobs;
var value raw_p;
run;
proc multtest pdata=fisher bon;
run;
You didn't say what problem you ran into, but this basic example works - note the newer option INPVALUES= which is a bit easier to work with.
ODS OUTPUT fishersexact(PERSIST)=fisher(WHERE=(name1="XP2_FISH"));
PROC FREQ DATA= test;
TABLES a*b;
exact fisher/mc;
RUN;
PROC FREQ DATA= test;
TABLES b*c;
exact fisher/mc;
RUN;
ODS OUTPUT CLEAR;
proc multtest inpvalues(nvalue1)=fisher bon;
run;
You probably still have that RENAME= option in the ODS OUTPUT line. Note that my code removes it.
This is what my code looks like, I have the rename statement removed.
ODS OUTPUT fishersexact(PERSIST)=winter_t1 (WHERE=(name1="XP2_FISH"));
PROC FREQ DATA= winter_t1;
WHERE platform in ('Facebook', 'Twitter');
TABLES platform*account_type;
exact fisher/mc;
RUN;
PROC FREQ DATA= winter_t1;
WHERE platform in ('Facebook', 'Instagram');
TABLES platform*account_type;
exact fisher/mc;
RUN;
PROC FREQ DATA= winter_t1;
WHERE platform in ('Twitter', 'Instagram');
TABLES platform*account_type;
exact fisher/mc;
RUN;
ODS OUTPUT CLEAR;
proc multtest inpvalues(nvalue1)=winter_t1 bon;
run;
Okay, I've changed the dataset in the ODS OUTPUT statement, I still seem to be getting an error from the proc multtest statement: ERROR: No valid observations.
And to clarify, I get output for the proc freq statements, so that's why I think the error has to do with the multtest statement.
Ok I have double checked and I still receive an error message saying there are 0 observations in the fisher dataset. My SAS code is below and my dataset attached. Thank you for all your help @StatDave !!
libname winterd "C:/Feb 2021";
proc import datafile="C:/Feb 2021/Winter_TEST.csv" out=table1
dbms=csv replace;
run;
*recoding 6 (formally coded as "other") to 4;
data table1;
set table1;
if account_type=6 then account_type=4;
run;
*checking to see this worked;
proc freq data=table1;
table account_type;
run;
*Frequency output of ACCOUNT_TYPE should be
1: 37
2: 198
3: 7
4: 40
5: 450;
*Fisher's exact test with MC. Resulting p value is significant;
proc freq data=table1;
tables platform*account_type;
exact fisher/mc;
run;
*proc multtest with bonferonni correction;
ODS OUTPUT fishersexact(PERSIST)=fisher(WHERE=(name1="XP2_FISH"));
PROC FREQ DATA= table1;
WHERE platform in (1,2);
TABLES platform*account_type;
exact fisher/mc;
RUN;
PROC FREQ DATA= table1;
WHERE platform in (1,3);
TABLES platform*account_type;
exact fisher/mc;
RUN;
PROC FREQ DATA= table1;
WHERE platform in (2,3);
TABLES platform*account_type;
exact fisher/mc;
RUN;
ODS OUTPUT CLEAR;
proc multtest inpvalues(nvalue1)=fisher bon;
run;
proc print data=fisher;
run;
@
Anytime you do something like this, you need to run the procedure once with your data to see exactly what tables are produced, which you want to work with, and exactly what its name is. Since these tables are larger than 2x2, you get a FisherExact table and a separate Monte Carlo table named FisherExactMC. Each has a p-value variable. If you save both of those tables with ODS OUTPUT, you will see that neither of them has a p-value variable called "XP2_FISH". That is the name of the variable in the FisherExact table if the table being analyzed is a 2x2 table. Depending on which p-value you want to use, this code does them both, using the correct variable names found by examining the tables that were produced for your data.
ODS OUTPUT fishersexact(PERSIST)=fisher(WHERE=(name1="P_TABLE"))
fishersexactmc(PERSIST)=fishmc(WHERE=(name1="MCP_FISH"));
PROC FREQ DATA= table1;
WHERE platform in (1,2);
TABLES platform*account_type;
exact fisher/mc;
RUN;
PROC FREQ DATA= table1;
WHERE platform in (1,3);
TABLES platform*account_type;
exact fisher/mc;
RUN;
PROC FREQ DATA= table1;
WHERE platform in (2,3);
TABLES platform*account_type;
exact fisher/mc;
RUN;
ODS OUTPUT CLEAR;
proc multtest inpvalues(nvalue1)=fisher bon;
run;
proc multtest inpvalues(nvalue1)=fishmc bon;
run;
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 25. 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.