Welcome to SAS
Part 2
1. Proc Reports
Although you can customize the output produced by PROC PRINT, there are times when
you need a bit more control over the appearance of your report. PROC REPORT was developed to fit this need. Not only can you control the appearance of every column of your report, you can produce summary reports as well as detail listings.
you need a bit more control over the appearance of your report. PROC REPORT was developed to fit this need. Not only can you control the appearance of every column of your report, you can produce summary reports as well as detail listings.
Two very useful features of PROC REPORT, multiple-panel reports and text wrapping within a column. We will look more about Proc Report by the following example.
#Problem:
Using the SAS data set Blood Pressure we have to create a new variable called Hypertensive which is mentioned as Yes for females (Gender=F) if the SBP is greater than 138 or the DBP is greater than 88 and No otherwise. For males (Gender=M), Hypertensive is defined as Yes if the SBP is over 140 or the DBP is over 90 and No otherwise.
#Data set:
#Solution:
#Output:
#Explanation:
#Problem:
Using the SAS data set Blood Pressure we have to create a new variable called Hypertensive which is mentioned as Yes for females (Gender=F) if the SBP is greater than 138 or the DBP is greater than 88 and No otherwise. For males (Gender=M), Hypertensive is defined as Yes if the SBP is over 140 or the DBP is over 90 and No otherwise.
#Data set:
*Creating Bloodpressure dataset; data A15011.A11_bloodpressure; input Gender : $1. Age SBP DBP; datalines; M 23 144 90 F 68 110 62 M 55 130 80 F 28 120 70 M 35 142 82 M 45 150 96 F 48 138 88 F 78 132 76 ;
#Solution:
title "Hypertensice Patients"; proc report data=A15011.A11_bloodpressure nowd; column Gender SBP DBP Hypertensive; define Gender / Group width=6; define SBP / display width=5; define DBP / display width=5; define Hypertensive / computed "Hypertensive?" width=13; compute Hypertensive / character length=3; if Gender = 'F' and (SBP gt 138 or DBP gt 88) then Hypertensive = 'Yes'; else Hypertensive='No'; if Gender = 'M' and (SBP gt 140 or DBP gt 90) then Hypertensive = 'Yes'; else Hypertensive = 'No'; endcomp; run; quit;
#Output:
In the above program we are trying to check whether the person is Hypertensive or not. For that we need an output based on the requirements which is explained in the problem statement. In the solution we use a statement called DEFINE which is used to specify the usage for each variable. Learning how to control whether to produce a detail listing or a summary report and what
statistics to produce leads you to the DEFINE statement. The DEFINE option DISPLAY is an instruction to produce a detailed listing of all observations. Besides defining the usage as DISPLAY, the DEFINE statement also carry a GROUP option when we need to club the data.
statistics to produce leads you to the DEFINE statement. The DEFINE option DISPLAY is an instruction to produce a detailed listing of all observations. Besides defining the usage as DISPLAY, the DEFINE statement also carry a GROUP option when we need to club the data.
Another import thing in the above program is COMPUTE. One powerful feature of PROC REPORT is its ability to compute new variables. This makes PROC REPORT somewhat unique among SAS procedures. We can use the compute statements to create a COMPUTE block where we can define the new variables inside the block. Here we compute whether he patient is Hypertensive or not based on the SBP and DB values using the IF else statements which we already learned. Also, we used quit statement to stop the procedure, otherwise it wont stop.
2. Proc Means
In this post, we will see about PROC Means which is more versatile and can be used to create summary data sets that can then be analyzed with more DATA or PROC steps.By default, PROC MEANS produces statistics on all the numeric variables in the input SAS data set. Let's see some examples.
#Problem:
Using the SAS data set College, report the mean GPA for the following categories of
ClassRank: 0–50 = bottom half, 51–74 = 3rd quartile, and 75 to 100 = top quarter.
#Dataset:
*Creating user defined format; proc format library=A15011; value $yesno 'Y','1' = 'Yes' 'N','0' = 'No' ' ' = 'Not Given'; value $size 'S' = 'Small' 'M' = 'Medium' 'L' = 'Large' ' ' = 'Missing'; value $gender 'F' = 'Female' 'M' = 'Male' ' ' = 'Not Given'; run; *Calling the format library; option FMTSEARCH=(A15011); *Creating college dataset; data A15011.A11_college; length StudentID $ 5 Gender SchoolSize $ 1; do i = 1 to 100; StudentID = put(round(ranuni(123456)*10000),z5.); if ranuni(0) lt .4 then Gender = 'M'; else Gender = 'F'; if ranuni(0) lt .3 then SchoolSize = 'S'; else if ranuni(0) lt .7 then SchoolSize = 'M'; else SchoolSize = 'L'; if ranuni(0) lt .2 then Scholarship = 'Y'; else Scholarship = 'N'; GPA = round(rannor(0)*.5 + 3.5,.01); if GPA gt 4 then GPA = 4; ClassRank = int(ranuni(0)*60 + 41); if ranuni(0) lt .1 then call missing(ClassRank); if ranuni(0) lt .05 then call missing(SchoolSize); if ranuni(0) lt .05 then call missing(GPA); output; end; format Gender $gender1. SchoolSize $size. Scholarship $yesno.; drop i; run;
#Solution:
proc format; value rank 0-50 = 'Bottom Half' 51-74 = 'Third Quartile' 75-100 = 'Top Quarter'; run; title "Statistics on the College Data Set"; title2 "Broken down by School Size"; proc means data=A15011.A11_college n mean maxdec=2; class ClassRank; var GPA; format ClassRank rank.; run;
#Output:
In the above program we tried to do some basic statistical calculation Mean which is to be said as average in the common man term. The data set which we used is College which we are seeing for most of the posts and that is not our interest of this post. So, we will concentrate on the solution part. The Proc Means procedure helps us to calculate the average of the variable. Here we are calculating the average of GPA based on the Class Rank where we created a range for the rank using Proc Format procedure. The options "n" gives the Number of persons and "Mean" gives the average value for that particular section of students and we can adjust the value as 2 decimal point by giving "Maxdec" option.
PROC MEANS lets you use a CLASS statement in place of a BY statement. The CLASS statement performs a similar function to the BY statement, with some significant differences. If you are using PROC MEANS to print a report and are not creating a summary output data set, the differences in the printed output between a BY and CLASS statement are basically cosmetic. The main difference, from a programmer’s perspective, is that you do not have to sort your data set before using a CLASS statement. Similarly, You can control which variables to include in the report by supplying a VAR statement.
3. PROC Tabulate
PROC TABULATE is an underused, under appreciated procedure that can create a wide
variety of tabular reports, displaying frequencies, percentages, and descriptive statistics such as sums and means) broken down by one or more CLASS variables. There are several excellent books devoted to PROC TABULATE. This posts introduces you to this procedure and, we hope, piques your interest.
#Problem:
Using the college data set which was given in my previous post, we should tabulate using the Proc Tabulate procedure.
#Solution:
#Output::
#Explanation:
PROC TABULATE uses a CLASS statement to allow you to specify variables that
represent categories (often character variables) where you want to compute frequencies
or percentages. So here we want to broke down the data based on the school size and type and Gender as well. Next, the TABLE statement specifies the table’s appearance. Any variable listed in a TABLE statement must be listed in a CLASS statement.
Apart from the above two keywords, we used format option which helps to display in the specific format for every cell in the table. Unlike many other SAS procedures, there are some reserved keywords used by PROC TABULATE and one such keyword is ALL. When you place ALL after a variable name in a table request, PROC TABULATE includes a column representing all levels of the preceding variable. Another customization option is RTS=, which increases the row title space (the space for the width of the row title, including the vertical lines).
#Solution:
title "Demographics from COLLEGE Data Set"; proc tabulate data=A15011.A11_college format=6.; class Gender Scholarship SchoolSize; tables SchoolSize all, Gender Scholarship all/ rts=15; keylabel n=' ' all = 'Total'; run;
#Output::
#Explanation:
PROC TABULATE uses a CLASS statement to allow you to specify variables that
represent categories (often character variables) where you want to compute frequencies
or percentages. So here we want to broke down the data based on the school size and type and Gender as well. Next, the TABLE statement specifies the table’s appearance. Any variable listed in a TABLE statement must be listed in a CLASS statement.
Apart from the above two keywords, we used format option which helps to display in the specific format for every cell in the table. Unlike many other SAS procedures, there are some reserved keywords used by PROC TABULATE and one such keyword is ALL. When you place ALL after a variable name in a table request, PROC TABULATE includes a column representing all levels of the preceding variable. Another customization option is RTS=, which increases the row title space (the space for the width of the row title, including the vertical lines).
Let us look another example where we can change the names of the variables in the Proc Tabulate Procedure.
#Solution:
#Output:
'
In the above output we can see that, the variable name "n" is changed as Number,"min" is changed as "Minimum" and similarly for max and avg. Thus usiing Proc Tabulate we can alter the table based on our needs to report the output.
#Solution:
title "Descriptive Statistics"; proc tabulate data=A15011.A11_college format=6.1; class Gender; var GPA; tables GPA*(n*f=4. mean min max), Gender all; keylabel n = 'Number' all = 'Total' mean = 'Average' min = 'Minimum' max = 'Maximum'; run;
#Output:
'
In the above output we can see that, the variable name "n" is changed as Number,"min" is changed as "Minimum" and similarly for max and avg. Thus usiing Proc Tabulate we can alter the table based on our needs to report the output.
4. Introduction to ODS
One of the most important changes in SAS, starting with Version 7, was the introduction of the Output Delivery System, abbreviated as ODS. Prior to ODS, each SAS procedure
produced its own unique output, usually featuring a non-proportional font.
Each SAS procedure creates output objects that can be sent to such destinations as HTML, RTF, PDF, and SAS data sets.There is now a separation between the results produced by each procedure and the delivery of this information. Not only can you send your SAS output to all of these formats, you can, if you are brave enough, customize the output’s fonts, colors, size, and
layout. Finally, you can now capture virtually every piece of SAS output to a SAS data
set for further processing.
#Problem:
Run the following program, sending the output to an HTML file. Issue the appropriate commands to prevent SAS from creating a listing file.
#Solution:
#Output:
#Explanation:
In the above example we tried to get the output as HTML page rather than the normal listing output. If you do not want a listing style output, use the ODS statement before the
ODS HTML FILE statement. Next. to get the output as an HTML file, we use the ODS html statement to give a local path so that tho output can be saved in that place as an HTML file. Finally, If you want to reinstate the listing output, use "ods listing" which will reinstate the listing output.
produced its own unique output, usually featuring a non-proportional font.
Each SAS procedure creates output objects that can be sent to such destinations as HTML, RTF, PDF, and SAS data sets.There is now a separation between the results produced by each procedure and the delivery of this information. Not only can you send your SAS output to all of these formats, you can, if you are brave enough, customize the output’s fonts, colors, size, and
layout. Finally, you can now capture virtually every piece of SAS output to a SAS data
set for further processing.
#Problem:
Run the following program, sending the output to an HTML file. Issue the appropriate commands to prevent SAS from creating a listing file.
title "Sending Output to an HTML File"; proc print data=learn.college(obs=8) noobs; run; proc means data=learn.college n mean maxdec=2; var GPA ClassRank; run;
#Solution:
options fmtsearch=(A15011); ods listing close; ods html file = '/folders/myfolders/prob19_1.html'; title "Sending Output to an HTML File"; proc print data=A15011.A11_college(obs=8) noobs; run; proc means data=A15011.A11_college n mean maxdec=2; var GPA ClassRank; run; ods html close; ods listing;
#Output:
#Explanation:
In the above example we tried to get the output as HTML page rather than the normal listing output. If you do not want a listing style output, use the ODS statement before the
ODS HTML FILE statement. Next. to get the output as an HTML file, we use the ODS html statement to give a local path so that tho output can be saved in that place as an HTML file. Finally, If you want to reinstate the listing output, use "ods listing" which will reinstate the listing output.
5. Generating High-Quality Graphics
In this post we speaks about some basic concepts behind SAS/GRAPH software. First you need to have SAS/GRAPH installed on your computer. Without it, you are relegated to using the older style “line printer” type plots using such procedures as PROC CHART and PROC PLOT.
These procedures are fine if you want a quick look at your data in graphical form; however, they are not suitable for presentations.
The appearance of graphs and charts is controlled by graphics options and global
statements such as SYMBOL and PATTERN. Options that are set using these statements
act somewhat like titles created using TITLE statements. That is, they remain in effect
until you change them and they are additive. For example, if you already have dots
selected as your plotting symbols, with the color set to black, and you change the color to
red, your plots display with red dots. Lets do some problems.
#Problem:
Using the SAS data set Bicycles, we want to produce two vertical bar charts showing frequencies for Country and Model. Use the PATTERN option VALUE=empty.
#Dataset:
#Solution:
#Output:
#Explanation:
There are lot of normal type of charts such as Proc Plot/Chart as said before, but it wont look like a feel good visuals. So creating a good graphical content there are lot of specific procedures such as gchart, gplot etc., which will gives some good graphical outputs. In the above example we used GPLOT procedure which produced the graphical content for your data. The VBAR and HBAR states abou the position of the graph like vertical or horizontal. Also we can give names for the axis xaxis and yaxis statement. Try the same graph using GCHART.
These procedures are fine if you want a quick look at your data in graphical form; however, they are not suitable for presentations.
The appearance of graphs and charts is controlled by graphics options and global
statements such as SYMBOL and PATTERN. Options that are set using these statements
act somewhat like titles created using TITLE statements. That is, they remain in effect
until you change them and they are additive. For example, if you already have dots
selected as your plotting symbols, with the color set to black, and you change the color to
red, your plots display with red dots. Lets do some problems.
#Problem:
Using the SAS data set Bicycles, we want to produce two vertical bar charts showing frequencies for Country and Model. Use the PATTERN option VALUE=empty.
#Dataset:
*Data set BICYCLES; data learn.bicycles; input Country & $25. Model & $14. Manuf : $10. Units : 5. UnitCost : comma8.; TotalSales = (Units * UnitCost) / 1000; format UnitCost TotalSales dollar10.; label TotalSales = "Sales in Thousands" Manuf = "Manufacturer"; datalines; USA Road Bike Trek 5000 $2,200 USA Road Bike Cannondale 2000 $2,100 USA Mountain Bike Trek 6000 $1,200 USA Mountain Bike Cannondale 4000 $2,700 USA Hybrid Trek 4500 $650 France Road Bike Trek 3400 $2,500 France Road Bike Cannondale 900 $3,700 France Mountain Bike Trek 5600 $1,300 France Mountain Bike Cannondale 800 $1,899 France Hybrid Trek 1100 $540 United Kingdom Road Bike Trek 2444 $2,100 United Kingdom Road Bike Cannondale 1200 $2,123 United Kingdom Hybrid Trek 800 $490 United Kingdom Hybrid Cannondale 500 $880 United Kingdom Mountain Bike Trek 1211 $1,121 Italy Hybrid Trek 700 $690 Italy Road Bike Trek 4500 $2,890 Italy Mountain Bike Trek 3400 $1,877 ;
#Solution:
title Freq of countries; proc sgplot data=A15011.A11_bicycles; vbar Country; xaxis label='Country'; run; title 'Freq of Models'; proc sgplot data=A15011.A11_bicycles; hbar Model; xaxis label='Count'; run;
#Output:
#Explanation:
There are lot of normal type of charts such as Proc Plot/Chart as said before, but it wont look like a feel good visuals. So creating a good graphical content there are lot of specific procedures such as gchart, gplot etc., which will gives some good graphical outputs. In the above example we used GPLOT procedure which produced the graphical content for your data. The VBAR and HBAR states abou the position of the graph like vertical or horizontal. Also we can give names for the axis xaxis and yaxis statement. Try the same graph using GCHART.
6. Proc FREQ
PROC FREQ can be used to count frequencies of both character and numeric variables, in one-way, two-way, and three-way tables. In addition, you can use PROC FREQ to create output data sets containing counts and percentages. Finally, if you are statistically inclined, you can use this procedure to compute various statistics such as chi-square, odds ratio, and relative risk.
#Problem:
Using the SAS data set Blood, we will generate one-way frequencies for the variables Gender, BloodType, and AgeGroup.
#Dataset:
Used in the previous example.
#Solution:
#Output:
#Explanation:
#Problem:
Using the SAS data set Blood, we will generate one-way frequencies for the variables Gender, BloodType, and AgeGroup.
#Dataset:
Used in the previous example.
#Solution:
title "One-way Frequencies from BLOOD Data Set"; proc freq data=A15011.A11_blood; tables Gender BloodType AgeGroup / nocum nopercent; run;
#Output:
#Explanation:
Here using the Proc freq procedure we can computes counts for each unique value of a variable. Here the TABLES statement to list the variables for which you want to compute
frequencies. Thus, in this example we are trying to calculate the frequencies for the variables Gender, Blood type and Age group. Secondly, w have used some option like NOCUM and NOPERCENT which tells PROC FREQ not to include the two cumulative statistics columns and percentages in the output, respectively.
The above example is single way frequency table and we can also produce two way or three way frequency tables. The below example shows how to produce three way frequency table. By using the college dataset we can build a three way freq table.
In the above program we try to get a freq table for Gender, Scholarship and School size. To built a multi way freq table we have to use (*) symbol between the variables. The output for the above program will looks like below.
#Output:
From the output, we got Gender wise 2 tables and each table shows whether they have scholarship or not and it is further classified based on the school type. Thus we can easily get the table format which will help us to classify based on the information we needed.
frequencies. Thus, in this example we are trying to calculate the frequencies for the variables Gender, Blood type and Age group. Secondly, w have used some option like NOCUM and NOPERCENT which tells PROC FREQ not to include the two cumulative statistics columns and percentages in the output, respectively.
The above example is single way frequency table and we can also produce two way or three way frequency tables. The below example shows how to produce three way frequency table. By using the college dataset we can build a three way freq table.
proc freq data=A15011.A11_college; tables Gender*Scholarship*SchoolSize; run;
#Output:
From the output, we got Gender wise 2 tables and each table shows whether they have scholarship or not and it is further classified based on the school type. Thus we can easily get the table format which will help us to classify based on the information we needed.



















