BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
LMSSAS
Quartz | Level 8

I am trying to solve for the following. Order my month in the below proc report so january is listed first, then october, november, december. Can I do this in proc report? My code is below the image

 

LMSSAS_0-1673357276414.png

proc report data = OUTPUT3 nowd split='|'  
style(header) = [font=("Arial",10.0pt) vjust=middle just=center background=%RGB(0,145,204) foreground=whitesmoke font_weight=bold]
style(column) = [font=("Arial",8.58pt) bordercolor=%RGB(242,242,242) ];
column Month '2023'n '2022'n Difference PERCENT_CHANGE ;

define Month / "Month" order=data; 
define '2023'n / "Submissions | 2023" style(column)={vjust=c just=c cellwidth = 1in} order=data; 
define '2022'n / "Submissions | 2022" style(column)={vjust=c just=c cellwidth = 1in} order=data;
define Difference / "YOY | Difference" style(column)={vjust=c just=c cellwidth = 1in} order=data;
define PERCENT_CHANGE / '% Change' format=percent8.2; 

/*rbreak after / summarize style=[fontweight=bold] ;*/

compute before _page_/style=[font=("Arial",12.5pt) vjust=middle just=center background=whitesmoke foreground=%RGB(0,145,204) font_weight=bold borderbottomcolor=%RGB(242,242,242)];
		 line 'Sales YoY Comparison by Month' ; endcomp;

compute 'Month'n;
	I + 1;
	if mod(i,2) eq 1 then
	call define(_row_, "style", "style=[background=%RGB(230,230,230)]");
endcomp;

/*compute after; 'Submit Date'n = Total; call define(_row_,'style','style={backgroundcolor=lightgray foreground=black font_weight=bold}'); endcomp; */

compute PERCENT_CHANGE;'% change'n=Difference.sum/'2022'n.sum ; endcomp; 

 run; 

1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26

If month is a numeric variable, with values 1 through 12, then the values will sort numerically, which seems to be what you want. But your variable MONTH is a text string, which sorts alphabetically, which is not what you want. IMPORTANT LESSON: calendar variables should be numeric ALWAYS (that's 100% of the time, no exceptions), NEVER character. Use formatting to make them look the way you want.

 

To do this, in a DATA step, create a new numeric variable that I shall call MONTH_NUM which is the month number 1 through 12. Assign a format to it — use format MONNAME8. Now, although it will sort numerically, the actual month names will appear in your PROC REPORT with January first.

 

In PROC REPORT, you will need something like this

 

define Month_num / "Month" order=internal format=monname8.;

Naturally, your COLUMN statement should also include MONTH_NUM instead of MONTH.

 

                                                                                                                                                                        

PART 2

Also, you have gone through the trouble to create variables name '2022'n and '2023'n, which is completely unnecessary, and makes you work much harder than if you let PROC REPORT create the YEAR columns for you, so you don't have to do it yourself. You will need a variable named YEAR which has values 2022 or 2023 and a variable named SUBMISSIONS which contains the number of submissions. In PROC REPORT you use 

 

define year/across "Submissions by Year";

 

You can even then compute the difference and percent difference right in PROC REPORT if you want, using a COMPUTE block for Difference and Percent Difference. 

 

If you want to use an ACROSS variable, and do these calculations within PROC REPORT, you would need to re-arrange your data (not shown) for this to work. So the final PROC REPORT (without all your formatting) ought to look like this (UNTESTED as I don't have your data)

 

proc report data=output3;
column month year,submissions yoy pct_chg;
define month/group order=internal format=monname8.;
define year/across order=data "Submissions for Year";
define submissions/sum " ";
define yoy/computed "YOY Diff";
define pct_chg/computed "% Change";
compute yoy;
    yoy=_c2_-_c3_;
endcompute;
compute pct_chg;
     pct_chg=(_c2_-_c3_)/_c3_;
endcompute;
run;

 

--
Paige Miller

View solution in original post

3 REPLIES 3
PaigeMiller
Diamond | Level 26

If month is a numeric variable, with values 1 through 12, then the values will sort numerically, which seems to be what you want. But your variable MONTH is a text string, which sorts alphabetically, which is not what you want. IMPORTANT LESSON: calendar variables should be numeric ALWAYS (that's 100% of the time, no exceptions), NEVER character. Use formatting to make them look the way you want.

 

To do this, in a DATA step, create a new numeric variable that I shall call MONTH_NUM which is the month number 1 through 12. Assign a format to it — use format MONNAME8. Now, although it will sort numerically, the actual month names will appear in your PROC REPORT with January first.

 

In PROC REPORT, you will need something like this

 

define Month_num / "Month" order=internal format=monname8.;

Naturally, your COLUMN statement should also include MONTH_NUM instead of MONTH.

 

                                                                                                                                                                        

PART 2

Also, you have gone through the trouble to create variables name '2022'n and '2023'n, which is completely unnecessary, and makes you work much harder than if you let PROC REPORT create the YEAR columns for you, so you don't have to do it yourself. You will need a variable named YEAR which has values 2022 or 2023 and a variable named SUBMISSIONS which contains the number of submissions. In PROC REPORT you use 

 

define year/across "Submissions by Year";

 

You can even then compute the difference and percent difference right in PROC REPORT if you want, using a COMPUTE block for Difference and Percent Difference. 

 

If you want to use an ACROSS variable, and do these calculations within PROC REPORT, you would need to re-arrange your data (not shown) for this to work. So the final PROC REPORT (without all your formatting) ought to look like this (UNTESTED as I don't have your data)

 

proc report data=output3;
column month year,submissions yoy pct_chg;
define month/group order=internal format=monname8.;
define year/across order=data "Submissions for Year";
define submissions/sum " ";
define yoy/computed "YOY Diff";
define pct_chg/computed "% Change";
compute yoy;
    yoy=_c2_-_c3_;
endcompute;
compute pct_chg;
     pct_chg=(_c2_-_c3_)/_c3_;
endcompute;
run;

 

--
Paige Miller
PaigeMiller
Diamond | Level 26

@LMSSAS 

I think a correction to what I said is warranted. Here is what I said, corrections in red:

 

If month is a numeric variable, with values of actual valid SAS dates spanning 12 months, then the values will sort numerically, which seems to be what you want. But your variable MONTH is a text string, which sorts alphabetically, which is not what you want. IMPORTANT LESSON: calendar variables should be numeric ALWAYS (that's 100% of the time, no exceptions), NEVER character. Use formatting to make them look the way you want.

 

To do this, in a DATA step, create a new numeric variable that I shall call MONTH_NUM which is the first day of the month for 12 months. 

 

month_num = mdy(month,1,2020);

where month is number 1 through 12, and the year part is irrelevant in this problem.

 

Assign a format to it — use format MONNAME8. Now, although it will sort numerically, the actual month names will appear in your PROC REPORT with January first.

 

In PROC REPORT, you will need something like this

 

define Month_num / "Month" order=internal format=monname8.;

Naturally, your COLUMN statement should also include MONTH_NUM instead of MONTH.

--
Paige Miller
ballardw
Super User

Another approach is to have a DATE value and use a custom format.

data junk;
  do i=1 to 1000;
     date= rand('integer',3000);
     output;
  end;
  format date date9.;
run;

proc format;
picture monthfromdate  (default=10)
low-high ='%B' (datatype=date);
run;

proc freq data=junk;
   tables date;
   format date monthfromdate.;
run;

If you have  month and year numbers it is easy to get a date using the MDY function:  mdy(month,1,year) creates a date value of the first of the month.

 

Note: having separate variables for year, like your '2023'n and '2022'n is inefficient. Next year you would have to add another variable, and another ... If you have values set up with Month, Year and a descriptive Value holding variable then you can use ACROSS for the Year variable and get columns for each year in your data in the report.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 498 views
  • 0 likes
  • 3 in conversation