Hi!
I want to show the grand total value in a subtotal row. Take for instance SASHELP.CLASS dataset. The total sum of weights of all the students is 1900.5. The sum of weights for male students is 1089.5, and for females is 811
I want to create a column that, for each student, shows the weight. But, for the Sex subtotals, shows 1900.5 both for M and F (instead of 1089.5 and 811)
I found a way of achieving it, but is a little awkward. I create a dummy column as weight divided by PCTSUM to get the total. Then I create a new column that shows either the value of weight or the dummy column.
I am sure there is a more straightforward way of achieving it. Any ideas? I tried using SUM instead of PCTSUM, but it doesn't calculate the grandtotal. Is there something like a TOTSUM function?
This is the code, the column that achieves the desired outcome is weightCustomSubtotal
PROC REPORT DATA=SASHELP.CLASS;
COLS SEX NAME AGE WEIGHT weight=dummy_pctsum totweight weightCustomSubtotal;
DEFINE SEX / GROUP;
DEFINE weightCustomSubotal / COMPUTED;
define dummy_pctsum / analysis PCTSUM 'dummy pctsum';
define dummy_totweight / COMPUTED;
compute totweight;
totweight = weight.sum / dummy_pctsum;
endcomp;
BREAK AFTER SEX / SUMMARIZE;
COMPUTE weightCustomSubtotal;
IF _BREAK_ = "" THEN
weightCustomSubtotal = weight.sum;
ELSE
weightCustomSubtotal = totweight;
ENDCOMP;
RUN;
Thanks a lot!!
Hi:
It's not clear what you want to do. Your code generates these warnings that point to some of the issues.
options missing=' ';
PROC REPORT DATA=SASHELP.CLASS out=repout;
column SEX NAME AGE WEIGHT weight=wpct subtot subpct;
DEFINE SEX / order;
define weight / analysis sum;
define wpct / analysis PCTSUM 'pctsum of grand tot' f=percent9.2;
define subtot / computed 'subtotal for group';
define subpct / computed 'pct of subgrp' f=percent9.2;
compute before sex;
holdsub = weight.sum;
endcomp;
compute subpct;
subtot = holdsub;
subpct = weight.sum /holdsub;
if upcase(_break_) = '_RBREAK_'
then subpct = .;
endcomp;
compute after sex;
name = 'SubTot';
endcomp;
compute after;
name = 'GrandTot';
subtot = .;
endcomp;
BREAK AFTER SEX / SUMMARIZE;
rbreak after / summarize;
RUN;
Hi:
It's not clear what you want to do. Your code generates these warnings that point to some of the issues.
options missing=' ';
PROC REPORT DATA=SASHELP.CLASS out=repout;
column SEX NAME AGE WEIGHT weight=wpct subtot subpct;
DEFINE SEX / order;
define weight / analysis sum;
define wpct / analysis PCTSUM 'pctsum of grand tot' f=percent9.2;
define subtot / computed 'subtotal for group';
define subpct / computed 'pct of subgrp' f=percent9.2;
compute before sex;
holdsub = weight.sum;
endcomp;
compute subpct;
subtot = holdsub;
subpct = weight.sum /holdsub;
if upcase(_break_) = '_RBREAK_'
then subpct = .;
endcomp;
compute after sex;
name = 'SubTot';
endcomp;
compute after;
name = 'GrandTot';
subtot = .;
endcomp;
BREAK AFTER SEX / SUMMARIZE;
rbreak after / summarize;
RUN;
Cynthia,
Thanks a lot for your reply! Your solution does work, the key in your code that I was missing is to create a hold variable in the compute before
Here's a simplified version of your code that calculates only the column that I need
options missing=' ';
PROC REPORT DATA=SASHELP.CLASS out=repout;
column sex name weight weightCustomSubtotal;
define sex / order;
define weight / noprint;
compute before;
holdtotal = weight.sum;
endcomp;
compute weightCustomSubtotal;
if _BREAK_ = 'Sex' THEN
weightCustomSubtotal = holdtotal;
else
weightCustomSubtotal = weight.sum;
endcomp;
BREAK AFTER SEX / SUMMARIZE;
RUN;
By the way, if I change sex from ORDER to GROUP it also works with no warnings. At least in SAS 9.4. See the code below
options missing=' ';
PROC REPORT DATA=SASHELP.CLASS out=repout;
column sex name weight weightCustomSubtotal;
define sex / group;
define weight / noprint;
compute before;
holdtotal = weight.sum;
endcomp;
compute weightCustomSubtotal;
if _BREAK_ = 'Sex' THEN
weightCustomSubtotal = holdtotal;
else
weightCustomSubtotal = weight.sum;
endcomp;
BREAK AFTER SEX / SUMMARIZE;
RUN;
Hi:
When I run in 9.4M6, I still see a NOTE with the SAME message. You got rid of the WARNINGS by fixing the COLUMN statement. Here's my log:
Do you see that NOTE? This is still something that you should consider fixing. When you have NAME in the report definition, you are NOT really "grouping" or collapsing rows. You are ORDERing the rows based on the value of the ORDER variable. And, yes, that treats each value of SEX as an ORDERed set --- for the purpose of BREAK processing. But in your usage scenario, the correct usage is ORDER.
Cynthia
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.