Delete Total Line in SAS - sas

Does anyone know of a way to remove the last blue total line?
This is the code I currently have:
title1 'Physical Exam Results By Patient';
footnote1;
proc print data=cert.transvisit1 noobs nosumlabel;
id ID;
var measure visitno1 visitno2 visitno3;
sum visitno1 visitno2 visitno3;
by ID;
run;

Related

How to PROC PRINT only the sum of a column of data

In SAS, you can use PROC PRINT to sum a column and display the sum:
proc print data = dataset.project_out;
sum variable;
run;
How can I get this function to only print the sum line and not the rest of the data?
I don't think you can do it with proc print. The closest you can come is the empty var statement:
proc print data=sashelp.class;
var ;
sum age;
run;
But sum adds the sum variable to the var list.
You can certainly accomplish this a number of other ways.
PROC SQL is the one I'd use:
proc sql;
select sum(Age) from sashelp.class;
quit;
PROC REPORT, often called "pretty PROC PRINT", can do it also:
proc report data=sashelp.class;
columns age;
define age/analysis sum;
run;
PROC TABULATE can do it:
proc tabulate data=sashelp.class;
var age;
tables age*sum;
run;
PROC MEANS:
proc means data=sashelp.class sum;
var age;
run;
Etc., plenty of ways to do the same thing.

Suppress Subtotal in Proc report

I have a proc report that groups and does subtotals. If I only have one observation in the group, the subtotal is useless. I'd like to either not do the subtotal for that line or not do the observation there. I don't want to go with a line statement, due to inconsistent formatting\style.
Here's some sample data. In the report the Tiki (my cat) line should only have one line, either the obs from the data or the subtotal...
data tiki1;
name='Tiki';
sex='C';
age=10;
height=6;
weight=9.5;
run;
data test;
set sashelp.class tiki1;
run;
It looks like you are trying do something that proc report cannot achieve in one pass. If however you just want the output you describe here is an approach that does not use proc report.
proc sort data = test;
by sex;
run;
data want;
length sex $10.;
set test end = eof;
by sex;
_tot + weight;
if first.sex then _stot = 0;
_stot + weight;
output;
if last.sex and not first.sex then do;
Name = "";
sex = "Subtotal " || trim(sex);
weight = _stot;
output;
end;
keep sex name weight;
if eof then do;
Name = "";
sex = "Total";
weight = _tot;
output;
end;
run;
proc print data = want noobs;
run;
This method manually creates subtotals and a total in the dataset by taking rolling sums. If you wanted do fancy formatting you could pass this data through proc report rather than proc print, Joe gives an example here.

Summing vertically across rows under conditions (sas)

County...AgeGrp...Population
A.............1..........200
A.............2..........100
A.............3..........100
A............All.........400
B.............1..........200
So, I have a list of counties and I'd like to find the under 18 population as a percent of the population for each county, so as an example from the table above I'd like to add only the population of agegrp 1 and 2 and divide by the 'all' population. In this case it would be 300/400. I'm wondering if this can be done for every county.
Let's call your SAS data set "HAVE" and say it has two character variables (County and AgeGrp) and one numeric variable (Population). And let's say you always have one observation in your data set for a each County with AgeGrp='All' on which the value of Population is the total for the county.
To be safe, let's sort the data set by County and process it in another data step to, creating a new data set named "WANT" with new variables for the county population (TOT_POP), the sum of the two Age Group values you want (TOT_GRP) and calculate the proportion (AgeGrpPct):
proc sort data=HAVE;
by County;
run;
data WANT;
retain TOT_POP TOT_GRP 0;
set HAVE;
by County;
if first.County then do;
TOT_POP = 0;
TOT_GRP = 0;
end;
if AgeGrp in ('1','2') then TOT_GRP + Population;
else if AgeGrp = 'All' then TOT_POP = Population;
if last.County;
AgeGrpPct = TOT_GRP / TOT_POP;
keep County TOT_POP TOT_GRP AgeGrpPct;
output;
run;
Notice that the observation containing AgeGrp='All' is not really needed; you could just as well have created another variable to collect a running total for all age groups.
If you want a procedural approach, create a format for the under 18's, then use PROC FREQ to calculate the percentage. It is necessary to exclude the 'All' values from the dataset with this method (it's generally bad practice to include summary rows in the source data).
PROC TABULATE could also be used for this.
data have;
input County $ AgeGrp $ Population;
datalines;
A 1 200
A 2 100
A 3 100
A All 400
B 1 200
B 2 300
B 3 500
B All 1000
;
run;
proc format;
value $age_fmt '1','2' = '<18'
other = '18+';
run;
proc sort data=have;
by county;
run;
proc freq data=have (where=(agegrp ne 'All')) noprint;
by county;
table agegrp / out=want (drop=COUNT where=(agegrp in ('1','2')));
format agegrp $age_fmt.;
weight population;
run;

Bar Graph by Month - SAS EG

I am trying to create a bar graph in SAS Enterprise Guide. The graph is Savings by Month.
The input Data is
Ref Date Savings
A 03JUN2013 1000
A 08JUN2013 2000
A 08JUL2013 1500
A 08AUG2013 300
A 08NOV2013 100
B 09DEC2012 500
B 09MAY2013 400
B 19MAY2013 5999
B 09OCT2013 511
C 15OCT2013 1200
C 01NOV2013 1500
The first step I do is to convert the date into month. The I use PROC MEANS to calculate total savings by month by Ref.
Then I create a bar graph. The issue I am getting is the bar graph is not in a sequential order as it should be. Like it is AUG13 JUl13 JUN13 .. etc. instead of JUN JUL AUG.
PROC SQL;
CREATE TABLE SAVINGS_11 AS
SELECT
PUT(DATE,monname3.) AS MONTH,
(DATE) FORMAT=MONNAME3. AS MONTH1,
MONTH(DATE) AS MONTH2,
PUT(DATE,MONYY5.) AS MONTH3,
(DATE) FORMAT=MONYY5. AS MONTH4,
DATE,
REF,
SAVINGS
FROM INPUT;
QUIT;
/* -------------------------------------------------------------------
Sort data set
------------------------------------------------------------------- */
PROC SORT
DATA=SAVINGS_11(KEEP=SAVINGS MONTH MONTH1 MONTH2 MONTH3 MONTH4 REF)
OUT=SORT1;
BY REF;
RUN;
/* -------------------------------------------------------------------
Run the Means Procedure
------------------------------------------------------------------- */
TITLE;
TITLE1 "Summary";
TITLE2 "Results";
FOOTNOTE;
PROC MEANS DATA=SORT1
NOPRINT
CHARTYPE
NOLABELS
NWAY
SUM NONOBS ;
VAR SAVINGS;
CLASS MONTH / ORDER=DATA ASCENDING;
BY REF;
ID MONTH1 MONTH2 MONTH3 MONTH4;
OUTPUT OUT=MEANSUMMARY
SUM()=
/ AUTONAME AUTOLABEL WAYS INHERIT
;
RUN;
/* -------------------------------------------------------------------
End of task code.
------------------------------------------------------------------- */
RUN; QUIT;
TITLE; FOOTNOTE;
PROC SORT
DATA=MEANSUMMARY(KEEP=MONTH MONTH2 "SAVINGS_Sum"n REF)
OUT=SORT2
;
BY REF MONTH2;
RUN;
Axis1
STYLE=1
WIDTH=1
MINOR=NONE
;
Axis2
STYLE=1
WIDTH=1
;
TITLE;
TITLE1 "Bar Chart";
FOOTNOTE;
PROC GCHART DATA=SORT2
;
VBAR
MONTH
/
SUMVAR="SAVINGS_Sum"n
CLIPREF
FRAME LEVELS=ALL
TYPE=SUM
INSIDE=SUM
COUTLINE=BLACK
RAXIS=AXIS1
MAXIS=AXIS2
;
BY REF;
/* -------------------------------------------------------------------
End of task code.
------------------------------------------------------------------- */
RUN; QUIT;
TITLE; FOOTNOTE;
Whatever format I use, the end result is not in a sequential order. Please help.
Your problem is that you're converting the date value to a character variable. MONTH, at least, should be a formatted date variable, not a character variable; so this line:
PUT(DATE,monname3.) AS MONTH,
should be
DATE AS MONTH FORMAT=monname3.,
Most procedures (like PROC MEANS and PROC GPLOT) will respect formats and group by same-formatted values. I don't completely understand why you have 5 month variables all containing different versions of the same thing, so perhaps there are better ways to do what you're doing here.
In particular, if you have SAS 9.2 or later, SGPLOT will probably do this entire process for you without any of the summarization steps.
Apart from what Joe mentioned above, you also need to include the key word DISCRETE in your VBAR statement if you want to be able to see all months for each reference on the x-axis where they made a saving (Note: this wil generate warning messages if some references do not have any savings in some months).
You could try the following code which I believe produces the output you are after:
PROC SQL;
CREATE TABLE DATA_TO_PLOT AS
SELECT
REF
,INPUT(PUT(date,YYMMN6.),YYMMN6.) FORMAT =DATE9. AS MONTH
,SUM(Savings) AS MONTHLY_SAVINGS
FROM INPUT
GROUP BY 1,2
ORDER BY 1,2 ;
QUIT;
Axis1 STYLE=1 WIDTH=1 MINOR=NONE;
Axis2 STYLE=1 WIDTH=1;
TITLE;
TITLE1 "Bar Chart";
PROC GCHART DATA=DATA_TO_PLOT;
VBAR MONTH
/ SUMVAR=MONTHLY_SAVINGS
CLIPREF
FRAME TYPE=SUM
COUTLINE=BLACK
RAXIS=AXIS1
MAXIS=AXIS2
INSIDE=SUM
DISCRETE
;
FORMAT MONTH MONYY7.;
BY Ref;
RUN; QUIT;

proc transpose with duplicate ID values

I need help with proc transpose procedure in SAS. My code initially was:
proc transpose data=temp out=temp1;
by patid;
var text;
Id datanumber;
run;
This gave me error "The ID value " " occurs twice in the same BY group". I modified the code to this:
proc sort data = temp;
by patid text datanumber;
run;
data temp;
set temp by patid text datanumber;
if first.datanunmber then n = 0;
n+1;
run;
proc sort data = temp;
by patid text datanumber n;
run;
proc transpose out=temp1 (drop=n) let;
by patid;
var text;
id datanumber;
run;
This is giving me error: variable n is not recognized. Adding a let option is giving a lot of error "occurs twice in the same BY group". I want to keep all id values.
Please help me in this.
Data Example:
Patid Text
When you get that error it is telling you that you have multiple data points for one or more variables that you are trying to create. SAS can force the transpose and delete the extra datapoints if you add "let" to the proc transpose line.
Your data is possibly not unique? I created a dataset (with unique values of patid and datanumber) and the transpose works:
data temp (drop=x y);
do x=1 to 4;
PATID='PATID'||left(x);
do y=1 to 3;
DATANUMBER='DATA'||left(y);
TEXT='TEXT'||left(x*y);
output;
end;
end;
proc sort; by _all_;
proc transpose out=temp2 (drop=_name_);
by patid;
var text;
id datanumber;
run;
my recommendation would be to forget the 'n' fix and focus on making the data unique for patid and datanumber, a dirty approach would be:
proc sort data = temp nodupkey;
by patid datanumber;
run;
at the start of your code..
Try to sort your dataset by patid text n datanumber, (n before datanumber).
Try to sort your dataset by patid n datanumber, (n before datanumber). and proc transpose "by patib n ";