简体   繁体   中英

SAS: Individual Table Titles for PROC FREQ or PROC REPORT?

Instead of performing multiple separate PROC FREQ procedures on a very large data set, I'd like to improve efficiency by performing a single PROC FREQ with multiple TABLE statements. Our QA process requires table titles which is simple with a single TABLE statement using a single TITLE statement, but is this possible with multiple TABLE statements?

Take the example data and code below:

DATA TEST;
    INPUT TEMPERATURE HUMIDITY PLATE FORM $12.;
    DATALINES;
    25  75  1   HOT
    30  75  2   COLD
    25  45  3   HOT
    30  45  4   COLD
    25  55  5   HOT
    30  55  6   COLD
    25  15  7   HOT
    30  15  8   COLD
    ;
RUN;

** SINGLE PASS ON PROC FREQ **;
PROC FREQ DATA = TEST;
    TITLE1 "TEMPERATURE FREQS";
      TABLE TEMPERATURE / LIST OUT=FREQS_TEMP;
    TITLE2 "HUMIDITY FREQS";
      TABLE HUMIDITY / LIST OUT=FREQS_HUM;
    TITLE3 "PLATE FREQS";
      TABLE PLATE / LIST OUT=FREQS_PLATE;
    TITLE4 "FORM FREQS";
      TABLE FORM / LIST OUT=FREQS_FORM;
RUN;TITLE1;TITLE2;TITLE3;TITLE4;

The titles stack on top of one another at the very top of the output rather than each table, so is something like this possible in the data step or does a custom template have to be created? Could PROC REPORT be a more viable option for custom frequencies?

One option, which is a bit of work but could be worth it if the dataset is very large, is to use proc document . I figure this is around the same amount of work that would go into outputting frequencies into separate tables and then doing a report or freq on those separately, and a bit less messy.

PROC DOCUMENT lets you edit the output object and then replay it. In your case, what you're missing in the freq is page breaks between tables - SAS only puts a title on the page header, so you don't get it between tables. I think PROC FREQ also doesn't create any tables until run , so the first three title statements don't do anything (yours do only because you use titel1/2/3/4 - if you used title each time, only the fourth would take effect).

You need to first add page breaks, then add the titles (you don't keep them unfortunately from the PROC FREQ, so you can take them out of that). So:

*ODS DOCUMENT creates the DOCUMENT object you will later modify;
ods document name=freqs(write);
** SINGLE PASS ON PROC FREQ **;
PROC FREQ DATA = TEST;
    TITLE "TEMPERATURE FREQS";
      TABLE TEMPERATURE / LIST OUT=FREQS_TEMP;
    TITLE "HUMIDITY FREQS";
      TABLE HUMIDITY / LIST OUT=FREQS_HUM;
    TITLE "PLATE FREQS";
      TABLE PLATE / LIST OUT=FREQS_PLATE;
    TITLE "FORM FREQS";
      TABLE FORM / LIST OUT=FREQS_FORM;
RUN;
title;
ods document close;


*PROC DOCUMENT is an interactive proc, so it stays active until QUIT;
proc document name=freqs;
  *Just a look at what it looks like under the hood - can be removed in production;
  list/levels=all;
run;

  *Here we create page breaks (OBPAGE command) after each table.;
  obpage \Freq#1\Table1#1\OneWayFreqs#1 /after;
  obpage \Freq#1\Table2#1\OneWayFreqs#1 /after;
  obpage \Freq#1\Table3#1\OneWayFreqs#1 /after;


  *Here we add the titles.;
  obtitle \Freq#1\Table1#1\OneWayFreqs#1 "TEMPERATURE FREQS";
  obtitle \Freq#1\Table2#1\OneWayFreqs#1 "HUMIDITY FREQS";
  obtitle \Freq#1\Table3#1\OneWayFreqs#1 "PLATE FREQS";
  obtitle \Freq#1\Table4#1\OneWayFreqs#1 "FORM FREQS";

  *And here we replay the document with the changes;
  replay ^;
run;

quit;

I'd suggest the macro route in this case. Probably saves on code in the long run as well. Create a macro with your PROC FREQ and call it multiple times.

%macro freq_out(VName, VSub);

proc freq data=test;
title "&VName Freqs";
table &vname/list out=freqs_&vsub;
run;

%mend;

%freq_out(Temperature, Temp);
%freq_out(Humidity, Hum);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM