Hi, I've been trying to get this 2x2 table (generated through proc freq) sorted so it shows 1 in the first column + row, and 0 in the second column + row. Even specifying "order=formatted", it still displays 0 in the first column + row which messes up some of the calculated stats. Any ideas what is going wrong here? Thank you!
proc format;
value noyes 1="Yes" 0="No" ;
run;
proc freq data=mydata.study order=formatted;
ods exclude riskdiffcol2;
tables ins*m1/nocol nopercent nocum riskdiff chisq;
format ins m1 noyes.;
run;
With order=formatted SAS will print the results based on sort order of the formatted values - No sorts before Yes.
You could use a lowercase n for no or add a leading blank to Yes to get the desired order in your report.
libname mydata "%sysfunc(pathname(work))";
data mydata.study;
do ins=0 to 1;
do m1=0 to 1;
output;
end;
end;
run;
proc format;
value noyes 1=" Yes" 0="No";
run;
proc freq data=mydata.study order=formatted;
ods exclude riskdiffcol2;
tables ins*m1/nocol nopercent nocum riskdiff chisq;
format ins m1 noyes.;
run;
It's sorting based on the format, as you specified - Yes sorts after No alphabetically.
By the way, if you're looking for the typical E+/E-, D+/D- (exposure status, disease status) as is common in epidemiology -- you can do that with these formats (and using order=formatted as you were). Keeping things as 0/1 is much more handy for other calculations.
proc format;
value fexp
0='E-'
1='E+'
;
value fdis
0='D-'
1='D+'
;
run;
proc freq data=test order=formatted;
format exp fexp. dis fdis.;
table exp*dis / missing norow nocol nopercent nocum chisq;
run;
Can you clarify why it matters what order the values appear in the table?
If the goal is just to print a 2x2 table why not use PROC FREQ to get the counts and then use PROC PRINT or PROC REPORT to make the printout?
You could convert your boolean 0=No 1=Yes values into 1=Yes 2=No values instead by subtracting from 2.
Example:
data have;
input a b count;
x=2-a;
y=2-b;
cards;
1 1 1
1 0 2
0 1 3
0 0 4
;
proc format ;
value yn 0='No' 1='Yes';
value ny 2='No' 1='Yes';
run;
proc freq data=have ;
ods exclude riskdiffcol2;
tables a*b/nocol nopercent nocum riskdiff chisq;
weight count;
format a b yn.;
run;
proc freq data=have ;
ods exclude riskdiffcol2;
tables x*y/nocol nopercent nocum riskdiff chisq;
weight count;
format x y ny.;
run;
Same counts, same labels, reversed order.
Table of a by b a b Frequency| Row Pct |No |Yes | Total ---------+--------+--------+ No | 4 | 3 | 7 | 57.14 | 42.86 | ---------+--------+--------+ Yes | 2 | 1 | 3 | 66.67 | 33.33 | ---------+--------+--------+ Total 6 4 10 Table of x by y x y Frequency| Row Pct |Yes |No | Total ---------+--------+--------+ Yes | 1 | 2 | 3 | 33.33 | 66.67 | ---------+--------+--------+ No | 3 | 4 | 7 | 42.86 | 57.14 | ---------+--------+--------+ Total 4 6 10
With order=formatted SAS will print the results based on sort order of the formatted values - No sorts before Yes.
You could use a lowercase n for no or add a leading blank to Yes to get the desired order in your report.
libname mydata "%sysfunc(pathname(work))";
data mydata.study;
do ins=0 to 1;
do m1=0 to 1;
output;
end;
end;
run;
proc format;
value noyes 1=" Yes" 0="No";
run;
proc freq data=mydata.study order=formatted;
ods exclude riskdiffcol2;
tables ins*m1/nocol nopercent nocum riskdiff chisq;
format ins m1 noyes.;
run;
Patrick already gave you the right solution.
Here is alternative way by using PROC SORT + ORDER=DATA .But you need make sure there are always have 0 and 1 in each row and column variable.
data study;
do ins=0 to 1;
do m1=0 to 1;
output;
end;
end;
run;
proc format;
value noyes 1="Yes" 0="No";
run;
proc sort data=study;by descending ins descending m1 ;run;
proc freq data=study order=data;
ods exclude riskdiffcol2;
tables ins*m1/nocol nopercent nocum riskdiff chisq;
format ins m1 noyes.;
run;
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.