%Let Pgm=TabVrsRpt; /*--------------------------*\ | | | | | Using proc report for | | higher dimensional tables | | instead of proc tabulate | | | | | \*--------------------------*/ /*--------------------------*\ | Create data | \*--------------------------*/ Data JobHrsSex ( Label="Create 3 dimensional table" Drop=Sal ); Retain Pge 0; Do Job="Cop","Jan","Pro","Tec"; Pge+1; /* Put each Job on a separate page */ Do Hrs="Ful","Nun","Par"; Do Sex="Fem","Mal"; Do Sal=50000 to 50050; JobHrs=Job!!Hrs; /* For Proc Report */ Pay=Sal+10000*normal(57313); If Uniform(8737) < .5 Then output; End; End; End; End; Call Symput('MaxPge',put(pge,1.)); Stop; Run; /* Job Hrs Sex JobHrs Pay Cop Ful Fem CopFul 47469.7 Cop Ful Fem CopFul 51520.8 Cop Ful Fem CopFul 49701.9 Cop Ful Fem CopFul 49638.2 Cop Ful Fem CopFul 37719.3 Cop Ful Fem CopFul 68524.3 Cop Ful Fem CopFul 57690.5 Cop Ful Fem CopFul 53061.9 Cop Ful Fem CopFul 21279.6 Cop Ful Fem CopFul 58321.3 */ /*--------------------------*\ | Tabulate Solution | \*--------------------------*/ Proc Tabulate data=JobHrsSex; Class Job Hrs Sex; Var Pay; Table Job=''*(Hrs='' All), ( Sex='' All )*Pay=''*N=''; run; /* ƒƒƒƒƒƒƒƒƒ…ƒƒƒƒƒƒƒƒ…ƒƒƒƒƒƒƒƒ…ƒƒƒƒƒƒƒƒ† ‚ ‚Fem ‚Mal ‚All ‚ ‡ƒƒƒƒƒ…ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚Cop ‚Ful‚ 23.00‚ 21.00‚ 44.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚Nun‚ 25.00‚ 25.00‚ 50.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚Par‚ 25.00‚ 34.00‚ 59.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚All‚ 73.00‚ 80.00‚ 153.00‚ ‡ƒƒƒƒƒˆƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚Jan ‚Ful‚ 33.00‚ 32.00‚ 65.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚Nun‚ 28.00‚ 28.00‚ 56.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚Par‚ 30.00‚ 30.00‚ 60.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚All‚ 91.00‚ 90.00‚ 181.00‚ ‡ƒƒƒƒƒˆƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚Pro ‚Ful‚ 28.00‚ 22.00‚ 50.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚Nun‚ 21.00‚ 23.00‚ 44.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚Par‚ 23.00‚ 27.00‚ 50.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚All‚ 72.00‚ 72.00‚ 144.00‚ ‡ƒƒƒƒƒˆƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚Tec ‚Ful‚ 29.00‚ 25.00‚ 54.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚Nun‚ 30.00‚ 28.00‚ 58.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚Par‚ 29.00‚ 24.00‚ 53.00‚ ‚ ‡ƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒˆƒƒƒƒƒƒƒƒ‰ ‚ ‚All‚ 88.00‚ 77.00‚ 165.00‚ Šƒƒƒƒƒ‹ƒƒƒ‹ƒƒƒƒƒƒƒƒ‹ƒƒƒƒƒƒƒƒ‹ƒƒƒƒƒƒƒƒŒ */ /*--------------------------*\ | I know you can use proc | | report here to approximate | | the Tabulate solution | | | | However, I like to use | | proc report as a print | | template and avoid | | across variables or | | summarization | | | | Functions like Page M of N | | Decimal Lineup, mixed | | alpha and numeric in a cell| | require preprocessing | | | \*--------------------------*/ /* Does what proc freq does but outputs a rectangular table */ Ods Exclude All; Ods Output Observed=JobHrsSexCor(Rename=Label=JobHrs); Proc Corresp Data=JobHrsSex Observed dim=1; By Pge Job; Table JobHrs, Sex; Run; Ods Select All; /* Job Label Fem Mal Sum Cop CopFul 23 21 44 Cop CopNun 25 25 50 Cop CopPar 25 34 59 Cop Sum 73 80 153 Jan JanFul 33 32 65 Jan JanNun 28 28 56 Jan JanPar 30 30 60 Jan Sum 91 90 181 */ proc template; define style LineUp; parent=styles.rtf; replace fonts / 'TitleFont2' = ("Arial",12pt,Normal) 'TitleFont' = ("Arial",12pt,Normal) 'StrongFont' = ("Arial",10.1pt) 'EmphasisFont' = ("Arial",10.1pt) 'headingEmphasisFont' = ("Arial",10.1pt) 'headingFont' = ("Arial",10.1pt) 'docFont' = ("Arial",10.1pt) 'EmphasisFont' = ("Arial",10.1pt) 'FixedEmphasisFont' = ("Courier",9pt) 'FixedStrongFont' = ("Courier",9pt) 'FixedHeadingFont' = ("Courier",9pt) 'BatchFixedFont' = ("Courier",6.7pt) 'FixedFont' = ("Courier",9pt); style table from table / rules=groups frame=box cellpadding = 2pt cellspacing = 2pt borderwidth = 0.5pt; replace Body from Document / bottommargin = 1in topmargin = 1in rightmargin = 1in leftmargin = 1.25in; replace HeadersAndFooters from Cell / font = fonts('docFont') foreground = colors('datafg') background = colors('databg') protectspecialchars=off; replace SystemFooter from TitlesAndFooters / font = fonts('docFont') just = l; end; run; quit; /* Create a deressed up proc tabulate */ Ods rtf file="d:\rtf\demtbl.rtf" style=LineUp; Ods EscapeChar='\'; Title; Footnote;run; Proc Report Data=JobHrsSexCor nowd ; Cols Pge Job JobHrs Hrs Fem Mal Sum ; %let hdr= %str(\S={font_weight=bold font_size=11pt just=left}); %let hdr0= %str(\S={font_weight=bold font_size=11pt just=left}); %let hdr1=%str(\S={font_weight=bold font_size=8pt font_style=italic just=left}); define Pge / display noprint order ; define Job / display noprint order ; define JobHrs / display noprint ; define Hrs / computed "&Hdr.Hours" Style={Just=r font_weight=bold} ; define Fem / display "&Hdr.Female" Style={Just=c} ; define Mal / display "&Hdr.Male" Style={Just=c} ; define Sum / display "&Hdr.Total" Style={Just=c font_weight=bold} ; compute Hrs / Char Length=3; If Length(Trim(JobHrs)) > 3 then do; Hrs=Substr(JobHrs,4); End; Else Hrs=JobHrs; EndComp; Break before Pge / Suppress Page; Compute Before _page_; MaxPge=%left(&MaxPge.); PgeNofM="&Hdr1.Page "!!put(Pge,1.)!!" of "!!put(MaxPge,1.); Line PgeNofM $96.; Line "&Hdr0.Alternative to Proc Tabulate for a Three Dimensional table"; EndComp; Compute Before Job; Length Txt $96; Dum ="\S={just=left}"!!'09'x; Line Dum $48.; Txt=left("&Hdr."!!left(Job)); Line Txt $96.; EndComp; Break after Pge / Suppress Page; Compute after Pge; Dum ="\S={just=left}"!!'09'x; Line Dum $48.; line "&Hdr1.\{super 1}For a more realistic example see /members.aol.com/xlr82sas/utl.html"; EndComp; run; quit; run; ods rtf close; run;