data have;
format setup_date date9.;
infile datalines;
input setup_date date9. Division $ cnt;
return;
datalines;
1Jun2018 Central 4
10Jun2018 Central 14
11Jun2018 Central 11
1May2018 Central 5
12May2018 Central 15
1Sep2018 Central 13
11Apr2019 Atlantic 13
17Apr2019 Atlantic 33
19Apr2019 Atlantic 3
1Feb2019 Atlantic 11
14Feb2019 Atlantic 21
1Jan2017 Pacific 11
13Jan2017 Pacific 13
14Jan2017 Pacific 14
1Mar2019 Central 11
14Mar2019 Central 13
;run;
data have2;
length Division $25.;
set have;
monthsum = month(setup_date);
year1=year(setup_date);
year2=put(year1,4.);
run;
/*setup_date date9. Division $ cnt monthsum */
proc report data=have2 NOWD Wrap style(summary)=Header;
columns Division year2 cnt monthsum;
define Division /group ;
define year2 /across order=data '';
define monthsum /noprint order = data;
define cnt /sum f=comma6. 'Row Tot';
compute after;
Division='Grand Total';
endcomp;
break after Division / ol summarize skip;
rbreak after /summarize;
run;
1. How can I structure so it displays the Year across by ascending order
2. How can I display the Row total by descending order
You will need to precompute the SUM(CNT) over each DIVISION and use that as a / GROUP DESCENDING NOPRINT variable.
The across variable is FORMATted and specified as ORDER=FORMATTED, or ORDER=INTERNAL, no-need for a precomputation that tears apart the setup_date. Also, no need to precompute a resized DIVISION, a computed variable can perform the same action directly in the REPORT.
Example:
data have; format setup_date date9.; infile datalines; input setup_date date9. Division $ cnt; return; datalines; 1Jun2018 Central 4 10Jun2018 Central 14 11Jun2018 Central 11 1May2018 Central 5 12May2018 Central 15 1Sep2018 Central 13 11Apr2019 Atlantic 13 17Apr2019 Atlantic 33 19Apr2019 Atlantic 3 1Feb2019 Atlantic 11 14Feb2019 Atlantic 21 1Jan2017 Pacific 11 13Jan2017 Pacific 13 14Jan2017 Pacific 14 1Mar2019 Central 11 14Mar2019 Central 13 ;run; proc sql; create table report_data as select *, sum(cnt) as div_cnt_sum /* precompute division level CNT sum for ordering rows */ from have group by division; ods html file='report.html' style=plateau; proc report data=report_data wrap style(summary)=Header; columns div_cnt_sum Division WiderDivision setup_date cnt ; define div_cnt_sum / group descending noprint ; /* orders the rows and is a 1x (i.e. non-impacting group) on Row Tot */ define Division / group noprint; /* groups for Row Tot */ define WiderDivision / 'Division' computed; /* in REPORT wider division for GRAND TOTAL */ define setup_date / across format=year4. order=internal ''; /* format across variable to show (and summarize group for N-count) based on only 4-digit year portion of setup_date */ define cnt / sum f=comma6. 'Row Tot'; /* report computed sum will match div_cnt_sum precomputed for row ordering */ break after Division / summarize; rbreak after / summarize; compute WiderDivision / character length=25; /* specify the widerness */ WiderDivision = Division; endcomp; compute after; WiderDivision='Grand Total'; endcomp; run; ods html close;
Output
You will need to precompute the SUM(CNT) over each DIVISION and use that as a / GROUP DESCENDING NOPRINT variable.
The across variable is FORMATted and specified as ORDER=FORMATTED, or ORDER=INTERNAL, no-need for a precomputation that tears apart the setup_date. Also, no need to precompute a resized DIVISION, a computed variable can perform the same action directly in the REPORT.
Example:
data have; format setup_date date9.; infile datalines; input setup_date date9. Division $ cnt; return; datalines; 1Jun2018 Central 4 10Jun2018 Central 14 11Jun2018 Central 11 1May2018 Central 5 12May2018 Central 15 1Sep2018 Central 13 11Apr2019 Atlantic 13 17Apr2019 Atlantic 33 19Apr2019 Atlantic 3 1Feb2019 Atlantic 11 14Feb2019 Atlantic 21 1Jan2017 Pacific 11 13Jan2017 Pacific 13 14Jan2017 Pacific 14 1Mar2019 Central 11 14Mar2019 Central 13 ;run; proc sql; create table report_data as select *, sum(cnt) as div_cnt_sum /* precompute division level CNT sum for ordering rows */ from have group by division; ods html file='report.html' style=plateau; proc report data=report_data wrap style(summary)=Header; columns div_cnt_sum Division WiderDivision setup_date cnt ; define div_cnt_sum / group descending noprint ; /* orders the rows and is a 1x (i.e. non-impacting group) on Row Tot */ define Division / group noprint; /* groups for Row Tot */ define WiderDivision / 'Division' computed; /* in REPORT wider division for GRAND TOTAL */ define setup_date / across format=year4. order=internal ''; /* format across variable to show (and summarize group for N-count) based on only 4-digit year portion of setup_date */ define cnt / sum f=comma6. 'Row Tot'; /* report computed sum will match div_cnt_sum precomputed for row ordering */ break after Division / summarize; rbreak after / summarize; compute WiderDivision / character length=25; /* specify the widerness */ WiderDivision = Division; endcomp; compute after; WiderDivision='Grand Total'; endcomp; run; ods html close;
Output
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 16. Read more here about why you should contribute and what is in it for you!
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.