Hello,
Is there a way to simplify the Proc Freq coding below? I have extra 8 variables similar to sex and age. If I do one single step each, I have to do 16 steps to get the results.
proc freq data=Have;
table Gender * RSV / chisq nopercent nocol out=Dataout_sex1;
where RSV in (1,2);
format RSV RSV. Gender Gender. ;
run;
proc freq data=Have;
table Gender * RSV / chisq nopercent nocol out=Dataout_sex2;
where RSV in (3,4);
format RSV RSV. Gender Gender. ;
run;
proc freq data=Have;
table Age * RSV / chisq nopercent nocol out=Dataout_age1;
where RSV in (1,2);
format RSV RSV. Age Age. ;
run;
proc freq data=Have;
table Age * RSV / chisq nopercent nocol out=Dataout_age2;
where RSV in (3,4);
format RSV RSV. Age Age. ;
run;
ODS output will allow you to place the results of multiple tables into a single data set.
You can use ( ) to group variables to create multiple tables in the tables statement: tables (a b c) * x creates tables a*x b*x and c*x.
Combine the two:
ods output crosstabfreqs=dataout1; proc freq data=Have; table ( Gender age ) * RSV / chisq nopercent nocol; where RSV in (1,2); format RSV RSV. Gender Gender. ; run;
Place the other variables in the ( ) with gender and age.
Not sure why you are filtering on RSV, so you still need to do two output sets. Note that the output data set may require some additional work to print "pretty" reports. There will be a variable that indicates which table a row of data comes from.
If you want a "pretty" output of counts you may want to consider a different procedure such as Proc Tabulate
proc tabulate data=have; class gender age <other variables go here>/missing; class rsv; tables gender age <other variables>, rsv*n ; run;
which will show the first row of variables, gender age etc as column on the left with each variable values, and column of RSV counts for each cell.
The formatted values of the variables will be used to create the row/column headings if you add them to the code.
Show sample data in form of data step. What output are you interested in freqs chisq etc. Show example.
The question is - What is your definition of simple. What you have already is simple just repetative.
Now if you want to automatically generate the repetative code you could do something like this:
/* Creae a macro with a single named parameter (multiWhere) */
/* multiWhere expects a list of where conditions seperated by a "/" */
%macro simple(multiWhere=) ;
/* The %put statements are for debugging/seeing what happens */
%put &=multiWhere ;
/* create a counter (n) */
%let n=1 ;
/* scan multiWhere for the nth word using / as a seperator */
%let where=%scan(&multiWhere,&n,"/") ;
%put &=n &=where ;
/* Repeat this step while &where has a value */
%do %while(&where ne ) ;
/* You code goes here */
proc freq data=sashelp.class ;
/* Note the Dataout_sex&n the &n will be replaced by the value of the counter (&n) */
table sex * age / out=Dataout_sex&n;
where sex in ("&where");
run;
/* Time to move onto the next Where clause */
/* Increment the counter */
%let n=%eval(&n+1) ;
/* Get the next where clause */
%let where=%scan(&multiWhere,&n,"/") ;
%put &=n &=where ;
%end ;
%mend ;
/* Call the simple macro, passing a list of where clauses */
%simple(multiWhere=M/F) ;
From the example you shared it looks like you have a 3rd category: if RSV is (1,2) vs RSV is (3.,4). If you make a dummy variable with that flag, perhaps you could then use PROC FREQ for an n-way analysis.
ODS output will allow you to place the results of multiple tables into a single data set.
You can use ( ) to group variables to create multiple tables in the tables statement: tables (a b c) * x creates tables a*x b*x and c*x.
Combine the two:
ods output crosstabfreqs=dataout1; proc freq data=Have; table ( Gender age ) * RSV / chisq nopercent nocol; where RSV in (1,2); format RSV RSV. Gender Gender. ; run;
Place the other variables in the ( ) with gender and age.
Not sure why you are filtering on RSV, so you still need to do two output sets. Note that the output data set may require some additional work to print "pretty" reports. There will be a variable that indicates which table a row of data comes from.
If you want a "pretty" output of counts you may want to consider a different procedure such as Proc Tabulate
proc tabulate data=have; class gender age <other variables go here>/missing; class rsv; tables gender age <other variables>, rsv*n ; run;
which will show the first row of variables, gender age etc as column on the left with each variable values, and column of RSV counts for each cell.
The formatted values of the variables will be used to create the row/column headings if you add them to the code.
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.