{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Statistical Analysis in SAS\n", "\n", "Now we are going to cover how to perform a variety of basic statistical tests in SAS.\n", "\n", "* Proportion tests\n", "* Chi-squared\n", "* Fisher’s Exact Test\n", "* Correlation\n", "* T-tests/Rank-sum tests\n", "* One-way ANOVA/Kruskal-Wallis\n", "* Linear Regression\n", "* Logistic Regression\n", "* Poisson Regression\n", "\n", "Note: We will be glossing over the statistical theory and “formulas” for these tests. There are plenty of resources online for learning more about these tests if you have not had a course covering this material. You will only be required to write code to fit or perform these test but will not be expected to interpret the results for this course.\n", "\n", "## Proportion Tests\n", "\n", "To conduct a test for one proportion, we can use PROC FREQ. To get this test, we use the BINOMIAL option in the TABLES statement. As options to BINOMIAL, we can specify\n", "\n", "* p= - the null value for the hypothesis test\n", "* level= - which group to use as a \"success\"\n", "* CORRECT - uses a continuity correction for calculating the p-value (can be useful for small sample sizes)\n", "* CL= - can select different types of CI such as WALD, EXACT, and LOGIT.\n", "\n", "
\n", "

Example

\n", "

In the following example, we use a summarized dataset, where we have the counts of the \"successes\" and \"failures\". In this case, we are interested in the proportion of smokers, so we have a count of smokers and a count of non-smokers.

\n", "
" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The FREQ Procedure

\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
smkstatusFrequencyPercentCumulative
Frequency
Cumulative
Percent
N1753.131753.13
Y1546.8832100.00
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Binomial Proportion
smkstatus = Y
Proportion0.4688
ASE0.0882
95% Lower Conf Limit0.2802
95% Upper Conf Limit0.6573
  
Exact Conf Limits 
95% Lower Conf Limit0.2909
95% Upper Conf Limit0.6526
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Test of H0: Proportion = 0.5
The asymptotic confidence limits and test
include a continuity correction.
ASE under H00.0884
Z-0.1768
One-sided Pr < Z0.4298
Two-sided Pr > |Z|0.8597
\n", "
\n", "
\n", "

Sample Size = 32

\n", "
\n", "
\n", "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "DATA smoke;\n", " INPUT smkstatus $ count;\n", " DATALINES;\n", "Y 15\n", "N 17\n", ";\n", "RUN;\n", "\n", "PROC FREQ data = smoke;\n", " TABLES smkstatus / binomial(p = 0.5 level = \"Y\" CORRECT) alpha = 0.05;\n", " WEIGHT count;\n", "RUN;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Note the use of the WEIGHT statement to specify the counts for Y and N. Without this statement SAS would read our data as having 1 Y and 1 N.

\n", "

The estimated proportion is 0.4688. The (asymptotic) 95% CI is (0.2802, 0.6573) and the two sided (continuity corrected) p-value for testing $H_0: p=0.5$ vs $H_a: p\\neq 0.5$ is 0.8597.

\n", "

Alternatively, we could have had the data listed out for each individual as follows.

\n", "
" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The FREQ Procedure

\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
smkstatusFrequencyPercentCumulative
Frequency
Cumulative
Percent
N1753.131753.13
Y1546.8832100.00
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Binomial Proportion
smkstatus = Y
Proportion0.4688
ASE0.0882
95% Lower Conf Limit0.2802
95% Upper Conf Limit0.6573
  
Exact Conf Limits 
95% Lower Conf Limit0.2909
95% Upper Conf Limit0.6526
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Test of H0: Proportion = 0.5
The asymptotic confidence limits and test
include a continuity correction.
ASE under H00.0884
Z-0.1768
One-sided Pr < Z0.4298
Two-sided Pr > |Z|0.8597
\n", "
\n", "
\n", "

Sample Size = 32

\n", "
\n", "
\n", "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "DATA smoke2;\n", " DO i = 1 to 15;\n", " smkstatus = \"Y\";\n", " OUTPUT;\n", " END;\n", " DO i = 1 to 17;\n", " smkstatus = \"N\";\n", " OUTPUT;\n", " END;\n", " DROP i;\n", "RUN;\n", "\n", "PROC FREQ data = smoke2;\n", " TABLES smkstatus / binomial(p = 0.5 level = \"Y\" CORRECT) alpha = 0.05;\n", "RUN;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Chi-squared Test\n", "\n", "To test for an association between two categorical variables, we could perform a chi-square test of independence. Again, we will use PROC FREQ with a tables statement. For 2x2 tables, a chi-square test is automatically performed, but for larger tables, we can request is by providing the CHISQ option to the tables statement. Another useful option to also specify is the EXPECTED option which provided the expected cell counts under the null hypothesis of independence. These expected cell counts are needed to assess whether or not the chi-square test is appropriate.\n", "\n", "
\n", "

Example

\n", "

The following example uses the Kaggle car auction dataset to test for an association between online sales and a car being a bad buy.

\n", "
" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The FREQ Procedure

\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "
\n", "
\n", "
Frequency
\n", "
Expected
\n", "
Percent
\n", "
Row Pct
\n", "
Col Pct
\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Table of IsBadBuy by IsOnlineSale
IsBadBuyIsOnlineSale
01Total
0\n", "
\n", "
62375
\n", "
62389
\n", "
85.47
\n", "
97.45
\n", "
87.68
\n", "
\n", "
\n", "
\n", "
1632
\n", "
1618.1
\n", "
2.24
\n", "
2.55
\n", "
88.46
\n", "
\n", "
\n", "
\n", "
64007
\n", "
 
\n", "
87.70
\n", "
 
\n", "
 
\n", "
\n", "
1\n", "
\n", "
8763
\n", "
8749.1
\n", "
12.01
\n", "
97.63
\n", "
12.32
\n", "
\n", "
\n", "
\n", "
213
\n", "
226.91
\n", "
0.29
\n", "
2.37
\n", "
11.54
\n", "
\n", "
\n", "
\n", "
8976
\n", "
 
\n", "
12.30
\n", "
 
\n", "
 
\n", "
\n", "
Total\n", "
\n", "
71138
\n", "
97.47
\n", "
\n", "
\n", "
\n", "
1845
\n", "
2.53
\n", "
\n", "
\n", "
\n", "
72983
\n", "
100.00
\n", "
\n", "
\n", "
\n", "
\n", "
\n", "

Statistics for Table of IsBadBuy by IsOnlineSale

\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
StatisticDFValueProb
Chi-Square10.99780.3178
Likelihood Ratio Chi-Square11.01540.3136
Continuity Adj. Chi-Square10.92740.3356
Mantel-Haenszel Chi-Square10.99780.3179
Phi Coefficient -0.0037 
Contingency Coefficient 0.0037 
Cramer's V -0.0037 
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Fisher's Exact Test
Cell (1,1) Frequency (F)62375
Left-sided Pr <= F0.1679
Right-sided Pr >= F0.8498
  
Table Probability (P)0.0177
Two-sided Pr <= P0.3324
\n", "
\n", "
\n", "

Sample Size = 72983

\n", "
\n", "
\n", "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "FILENAME cardata '/folders/myfolders/SAS_Notes/data/kaggleCarAuction.csv';\n", "\n", "PROC IMPORT datafile = cardata out = cars dbms = CSV replace;\n", " getnames = yes;\n", " guessingrows = 1000;\n", "RUN;\n", "\n", "PROC FREQ data = cars;\n", " TABLES isbadbuy*isonlinesale / chisq expected;\n", "RUN;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

The chi-square test results in a p-value of 0.3178, or if we use the chi-square test with continuity correction, then we get a p-value of 0.3356.

\n", "

In the 2x2 case, as in this example, we may also want measures of effert such as the risk difference, relative risk and odds ratio. We can obtain these using the RISKDIFF, RELRISK, and OR options which will request all three measures with confidence intervals.

\n", "
" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The FREQ Procedure

\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "
\n", "
\n", "
Frequency
\n", "
Percent
\n", "
Row Pct
\n", "
Col Pct
\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Table of IsBadBuy by IsOnlineSale
IsBadBuyIsOnlineSale
01Total
0\n", "
\n", "
62375
\n", "
85.47
\n", "
97.45
\n", "
87.68
\n", "
\n", "
\n", "
\n", "
1632
\n", "
2.24
\n", "
2.55
\n", "
88.46
\n", "
\n", "
\n", "
\n", "
64007
\n", "
87.70
\n", "
 
\n", "
 
\n", "
\n", "
1\n", "
\n", "
8763
\n", "
12.01
\n", "
97.63
\n", "
12.32
\n", "
\n", "
\n", "
\n", "
213
\n", "
0.29
\n", "
2.37
\n", "
11.54
\n", "
\n", "
\n", "
\n", "
8976
\n", "
12.30
\n", "
 
\n", "
 
\n", "
\n", "
Total\n", "
\n", "
71138
\n", "
97.47
\n", "
\n", "
\n", "
\n", "
1845
\n", "
2.53
\n", "
\n", "
\n", "
\n", "
72983
\n", "
100.00
\n", "
\n", "
\n", "
\n", "
\n", "
\n", "

Statistics for Table of IsBadBuy by IsOnlineSale

\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Column 1 Risk Estimates
 RiskASE95%
Confidence Limits
Exact 95%
Confidence Limits
Difference is (Row 1 - Row 2)
Row 10.97450.00060.97330.97570.97330.9757
Row 20.97630.00160.97310.97940.97290.9793
Total0.97470.00060.97360.97590.97360.9758
Difference-0.00180.0017-0.00510.0016  
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Column 2 Risk Estimates
 RiskASE95%
Confidence Limits
Exact 95%
Confidence Limits
Difference is (Row 1 - Row 2)
Row 10.02550.00060.02430.02670.02430.0267
Row 20.02370.00160.02060.02690.02070.0271
Total0.02530.00060.02410.02640.02420.0264
Difference0.00180.0017-0.00160.0051  
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Odds Ratio and Relative Risks
StatisticValue95% Confidence Limits
Odds Ratio0.92900.80401.0735
Relative Risk (Column 1)0.99820.99471.0016
Relative Risk (Column 2)1.07450.93311.2373
\n", "
\n", "
\n", "

Sample Size = 72983

\n", "
\n", "
\n", "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PROC FREQ data = cars;\n", " TABLES isbadbuy*isonlinesale / RISKDIFF RELRISK OR;\n", "RUN;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

For the risk difference, SAS provides two tables that compare the conditional row proportions in the first column and the conditional row proportions in the second column. Similarly, for the relative risk, we get a relative risk for the first and the second column. This allows us to pick the one that matters to us depending on which column corresponds to the outcome of interest.

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fisher's Exact Test\n", "\n", "An alternative way to test for an association between two categorical variables is Fisher's exact test. This test is a nonparametric test that makes no assumption other than that we have a random sample. Note, however, that this comes with a price. The more levels our variables have and the more observations we have will increase the computing time needed to perform this test. For 2x2 tables, this test is usally very quick, but for 5x5 tables, depending on how much data and what computer you are using, this test may take hours to complete.\n", "\n", "For 2x2 tables, this test is automatically output. For larger tables, if you want this test, then you will need to specify the FISHER option in the TABLES statement.\n", "\n", "
\n", "

Example

\n", "

The following SAS program uses Fisher's exact test to test for an association between a car being a bad buy and buying the car online.

\n", "
" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The FREQ Procedure

\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "
\n", "
\n", "
Frequency
\n", "
Percent
\n", "
Row Pct
\n", "
Col Pct
\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Table of IsBadBuy by IsOnlineSale
IsBadBuyIsOnlineSale
01Total
0\n", "
\n", "
62375
\n", "
85.47
\n", "
97.45
\n", "
87.68
\n", "
\n", "
\n", "
\n", "
1632
\n", "
2.24
\n", "
2.55
\n", "
88.46
\n", "
\n", "
\n", "
\n", "
64007
\n", "
87.70
\n", "
 
\n", "
 
\n", "
\n", "
1\n", "
\n", "
8763
\n", "
12.01
\n", "
97.63
\n", "
12.32
\n", "
\n", "
\n", "
\n", "
213
\n", "
0.29
\n", "
2.37
\n", "
11.54
\n", "
\n", "
\n", "
\n", "
8976
\n", "
12.30
\n", "
 
\n", "
 
\n", "
\n", "
Total\n", "
\n", "
71138
\n", "
97.47
\n", "
\n", "
\n", "
\n", "
1845
\n", "
2.53
\n", "
\n", "
\n", "
\n", "
72983
\n", "
100.00
\n", "
\n", "
\n", "
\n", "
\n", "
\n", "

Statistics for Table of IsBadBuy by IsOnlineSale

\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
StatisticDFValueProb
Chi-Square10.99780.3178
Likelihood Ratio Chi-Square11.01540.3136
Continuity Adj. Chi-Square10.92740.3356
Mantel-Haenszel Chi-Square10.99780.3179
Phi Coefficient -0.0037 
Contingency Coefficient 0.0037 
Cramer's V -0.0037 
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Fisher's Exact Test
Cell (1,1) Frequency (F)62375
Left-sided Pr <= F0.1679
Right-sided Pr >= F0.8498
  
Table Probability (P)0.0177
Two-sided Pr <= P0.3324
\n", "
\n", "
\n", "

Sample Size = 72983

\n", "
\n", "
\n", "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PROC FREQ data = cars;\n", " TABLES isbadbuy*isonlinesale / FISHER;\n", "RUN;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

The p-value for Fisher's exact test is 0.3324.

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Correlation\n", "\n", "SAS's CORR procedure can perform correlation analysis by providing both the parametric Pearson's correlation and the nonparametric Spearman's rank correlation coefficients and hypothesis tests. The default correlation output is Pearson's. To request the Spearman's rank correlation, add the SPREAMAN option to the PROC CORR statement.\n", "\n", "
\n", "

Example

\n", "

Let's look at some examples using PROC CORR using the Charm City Circulator bus ridership dataset. The following SAS program will find the Pearson correlation and hypothesis test results for the correlation between the average daily ridership between the orange and purple bus lines.

\n", "
" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The CORR Procedure

\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
2 Variables:orangeAverage purpleAverage
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Simple Statistics
VariableNMeanStd DevSumMinimumMaximum
orangeAverage113630331228344567106927
purpleAverage99340171407398881608090
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Pearson Correlation Coefficients
Prob > |r| under H0: Rho=0
Number of Observations
 orangeAveragepurpleAverage
orangeAverage\n", "
\n", "
1.00000
\n", "
 
\n", "
1136
\n", "
\n", "
\n", "
\n", "
0.91954
\n", "
<.0001
\n", "
993
\n", "
\n", "
purpleAverage\n", "
\n", "
0.91954
\n", "
<.0001
\n", "
993
\n", "
\n", "
\n", "
\n", "
1.00000
\n", "
 
\n", "
993
\n", "
\n", "
\n", "
\n", "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "FILENAME busdata '/folders/myfolders/SAS_Notes/data/Charm_City_Circulator_Ridership.csv';\n", "\n", "PROC IMPORT datafile = busdata out = circ dbms = CSV replace;\n", " getnames = yes;\n", " guessingrows = 1000;\n", "RUN;\n", "\n", "PROC CORR data = circ;\n", " VAR orangeAverage purpleAverage;\n", "RUN;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Example

\n", "

We can also get a correlation matrix for multiple variables at the same time. The following example also uses the NOMISS option to only use complete observations instead of pairwise complete observations when calculating the correlations. Here we get the correlation matrix between average ridership counts between all four of the orange, purple, banner, and green bus lines.

\n", "
" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The CORR Procedure

\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
4 Variables:orangeAverage purpleAverage greenAverage bannerAverage
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Simple Statistics
VariableNMeanStd DevSumMinimumMaximum
orangeAverage27038591095104189006927
purpleAverage27045521297122893508090
greenAverage2702090556.0035356421303879
bannerAverage270827.26852436.0487222336304617
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Pearson Correlation Coefficients, N = 270
Prob > |r| under H0: Rho=0
 orangeAveragepurpleAveragegreenAveragebannerAverage
orangeAverage\n", "
\n", "
1.00000
\n", "
 
\n", "
\n", "
\n", "
\n", "
0.90788
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
0.83958
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
0.54470
\n", "
<.0001
\n", "
\n", "
purpleAverage\n", "
\n", "
0.90788
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
1.00000
\n", "
 
\n", "
\n", "
\n", "
\n", "
0.86656
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
0.52135
\n", "
<.0001
\n", "
\n", "
greenAverage\n", "
\n", "
0.83958
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
0.86656
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
1.00000
\n", "
 
\n", "
\n", "
\n", "
\n", "
0.45334
\n", "
<.0001
\n", "
\n", "
bannerAverage\n", "
\n", "
0.54470
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
0.52135
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
0.45334
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
1.00000
\n", "
 
\n", "
\n", "
\n", "
\n", "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PROC CORR data = circ NOMISS;\n", " VAR orangeAverage purpleAverage greenAverage bannerAverage;\n", "RUN;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

If we don't want all pairwise correlations, but instead only specific pairs, then we can use the WITH statement as in the following example.

\n", "
" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The CORR Procedure

\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
2 With Variables:greenAverage bannerAverage
2 Variables:orangeAverage purpleAverage
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Simple Statistics
VariableNMeanStd DevSumMinimumMaximum
greenAverage2702090556.0035356421303879
bannerAverage270827.26852436.0487222336304617
orangeAverage27038591095104189006927
purpleAverage27045521297122893508090
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Pearson Correlation Coefficients, N = 270
Prob > |r| under H0: Rho=0
 orangeAveragepurpleAverage
greenAverage\n", "
\n", "
0.83958
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
0.86656
\n", "
<.0001
\n", "
\n", "
bannerAverage\n", "
\n", "
0.54470
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
0.52135
\n", "
<.0001
\n", "
\n", "
\n", "
\n", "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PROC CORR data = circ NOMISS;\n", " VAR orangeAverage purpleAverage;\n", " WITH greenAverage bannerAverage;\n", "RUN;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get Spearman's rank correlation instead of Pearson's correlation, add the SPEARMAN option to the PROC CORR statement.\n", "\n", "
\n", "

Example

\n", "

The following SAS program produces Spearman's rank correlation coefficient and associated p-value for the hypothesis test of the correlation is 0 between the average daily ridership counts betwen the orange and purple bus lines.

\n", "
" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The CORR Procedure

\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
2 Variables:orangeAverage purpleAverage
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Simple Statistics
VariableNMeanStd DevMedianMinimumMaximum
orangeAverage113630331228296806927
purpleAverage99340171407422308090
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Spearman Correlation Coefficients
Prob > |r| under H0: Rho=0
Number of Observations
 orangeAveragepurpleAverage
orangeAverage\n", "
\n", "
1.00000
\n", "
 
\n", "
1136
\n", "
\n", "
\n", "
\n", "
0.91455
\n", "
<.0001
\n", "
993
\n", "
\n", "
purpleAverage\n", "
\n", "
0.91455
\n", "
<.0001
\n", "
993
\n", "
\n", "
\n", "
\n", "
1.00000
\n", "
 
\n", "
993
\n", "
\n", "
\n", "
\n", "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PROC CORR data = circ SPEARMAN;\n", " VAR orangeAverage purpleAverage;\n", "RUN;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## T-Tests\n", "\n", "T-tests can be performed in SAS with the TTEST procedure including\n", "\n", "* one sample t-test\n", "* paired t-test\n", "* Two sample t-test\n", "\n", "
\n", "

Example

\n", "

In this example, we will test if the average daily ridership on the orange bus line is greater than 3000 using a one sample t-test.

\n", "
" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The TTEST Procedure

\n", "

 

\n", "

Variable: orangeAverage

\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
NMeanStd DevStd ErrMinimumMaximum
11363033.21227.636.421706926.5
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Mean95% CL MeanStd Dev95% CL Std Dev
3033.22973.2Infty1227.61179.11280.3
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
DFt ValuePr > t
11350.910.1814
\n", "
\n", "
\n", "
\n", "\"Summary\n", "
\n", "
\n", "
\n", "
\n", "\"Q-Q\n", "
\n", "
\n", "
\n", "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PROC TTEST data = circ H0 = 3000 SIDE = U;\n", " VAR orangeAverage;\n", "RUN;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

The H0= option specifies the null value in the t-test and the SIDE= option specifies whether you want a less than (L), greater than (U), or not equal to (2) test. The default values are 0 for the null hypothesis value and two sided (2) for the alternative hypothesis. The output provides some summary statistics, the p-value for the test, confidence interval and a histogram and QQ plot to assess the normality assumption.

\n", "

From the output, we find the p-value to be 0.1814. Since we requested a one-side test, we get a one-sided confidence interval. To get our usual (two-sided) confidence interval, we need to request a two-sided test.

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For a two sample t-test, we need to have the data formatted in two columns:\n", "\n", "* A data column that contains the quantitative data for both groups\n", "* A grouping variable column that indicates the group for the data value in that row.\n", "\n", "In PROC TTEST, we put the data variable in the VAR statement and the grouping variable in the CLASS statement to get a two sample t-test.\n", "\n", "
\n", "

Example

\n", "

In the following SAS program, we perform a two-sample t-test between the orange and purple bus lines' average ridership counts. We will first have to transform the data to meet the required data format for PROC TTEST.

\n", "
" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The TTEST Procedure

\n", "

 

\n", "

Variable: count

\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
groupMethodNMeanStd DevStd ErrMinimumMaximum
orange 11363033.21227.636.421706926.5
purple 9934016.91406.744.638808089.5
Diff (1-2)Pooled -983.81314.157.0906  
Diff (1-2)Satterthwaite -983.8 57.6122  
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
groupMethodMean95% CL MeanStd Dev95% CL Std Dev
orange 3033.22961.73104.61227.61179.11280.3
purple 4016.93929.34104.51406.71347.41471.4
Diff (1-2)Pooled-983.8-1095.7-871.81314.11275.81354.9
Diff (1-2)Satterthwaite-983.8-1096.8-870.8   
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
MethodVariancesDFt ValuePr > |t|
PooledEqual2127-17.23<.0001
SatterthwaiteUnequal1984-17.08<.0001
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Equality of Variances
MethodNum DFDen DFF ValuePr > F
Folded F99211351.31<.0001
\n", "
\n", "
\n", "
\n", "\"Summary\n", "
\n", "
\n", "
\n", "
\n", "\"Q-Q\n", "
\n", "
\n", "
\n", "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "DATA circ_sub;\n", " SET circ;\n", " count = orangeAverage;\n", " group = \"orange\";\n", " OUTPUT;\n", " count = purpleAverage;\n", " group = \"purple\";\n", " OUTPUT;\n", " KEEP count group;\n", "RUN;\n", "\n", "PROC TTEST data = circ_sub;\n", " VAR count;\n", " CLASS group;\n", "RUN;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

The SAS output contains summary statistics for each group, confidence intervals for each group mean, confidence intervals for the difference of the two means, hypothesis tests for the difference of the two means, and the F test for equality of variances. The Pooled row corresponds to the two sample t-test which assumes the population variances are equal between the two groups while the Satterthwaite assumes that the population variances are unequal.

\n", "

Note that the data here are really matched pairs data, since we have average ridership counts matched by date between the two bus lines. We will explore the paired t-test next.

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To perform a paired t-test, we need to use the PAIRED statement. In this case, SAS assumes the data from each group are in two separate columns where observations in the same row correspond to the matched pairs.\n", "\n", "
\n", "

Example

\n", "

The following SAS program performs a paired t-test betwen the average ridership counts between the orange and purple bus lines.

\n", "
" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "SAS Output\n", "\n", "\n", "\n", "
\n", "
\n", "
\n", "

The SAS System

\n", "
\n", "
\n", "

The TTEST Procedure

\n", "

 

\n", "

Difference: orangeAverage - purpleAverage

\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
NMeanStd DevStd ErrMinimumMaximum
993-764.1572.318.1613-2998.02504.5
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Mean95% CL MeanStd Dev95% CL Std Dev
-764.1-799.8-728.5572.3548.2598.6
\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
DFt ValuePr > |t|
992-42.08<.0001
\n", "
\n", "
\n", "
\n", "\"Summary\n", "
\n", "
\n", "
\n", "
\n", "