SAS econometrics starts with a deceptively simple question in this lab. How much fertilizer did a farm use per unit of corn? Ten annual records produce two defensible answers. The choice depends on whether you give each year or each unit of output equal weight. That same habit of asking what a number measures will help you read a regression, a probability, an instrumental-variable estimate, and a forecast test.
Work through the first two examples with the complete farm data below. Then compare two probability models on a common scale, trace a two-stage regression, and reconstruct a six-lag test from its output. Each example ends with a numerical check you can use when your own results differ.
Data and scope. The numerical examples use the teaching data and output in Chapter 12, “Computer Applications in Econometrics,” pp. 282–293, supplied for this article. Our year-by-year calculations, weighting comparison, sensitivity checks, and probability chart below use those figures. The money and Granger sections identify results that rely on printed output because the supplied pages omit their underlying series. Treat these as historical classroom examples. The tables do not establish current agricultural or macroeconomic relationships.
1. Build and summarize the farm data
Start with one row per year. Corn is the output measure, while fertilizer and insecticide are input measures. The excerpt supplies numerical values without physical units. Consequently, the ratio below means input units per output unit. Keep that label until a data dictionary establishes whether the original measurements refer to pounds, bushels, hectares, or another basis.
| Year | Corn | Fertilizer | Insecticide | Fertilizer / corn |
|---|---|---|---|---|
| 1971 | 40 | 6 | 4 | 0.15000 |
| 1972 | 44 | 10 | 4 | 0.22727 |
| 1973 | 46 | 12 | 5 | 0.26087 |
| 1974 | 48 | 14 | 7 | 0.29167 |
| 1975 | 52 | 16 | 9 | 0.30769 |
| 1976 | 58 | 18 | 12 | 0.31034 |
| 1977 | 60 | 22 | 14 | 0.36667 |
| 1978 | 68 | 24 | 20 | 0.35294 |
| 1979 | 74 | 26 | 21 | 0.35135 |
| 1980 | 80 | 32 | 24 | 0.40000 |
Enter the records and check the denominator
data farm;
input year corn fert insect;
if corn > 0 then ratio = fert / corn;
datalines;
1971 40 6 4
1972 44 10 4
1973 46 12 5
1974 48 14 7
1975 52 16 9
1976 58 18 12
1977 60 22 14
1978 68 24 20
1979 74 26 21
1980 80 32 24
;
run;
proc sort data=farm; by year; run;
proc means data=farm n mean std min max maxdec=5;
var corn fert insect ratio;
run;
For a CSV with a header, replace the DATALINES statement and its records with an INFILE statement before INPUT. Specifically, use infile "/your/path/farm.csv" dsd firstobs=2 truncover; and keep the same column order. If the file contains a row number between year and corn, add that field to INPUT. Otherwise, SAS can read valid numbers into the wrong columns without an obvious type error.
| Variable | Count | Mean | Sample SD | Range |
|---|---|---|---|---|
| Corn | 10 | 57.00000 | 13.47426 | 40.000–80.000 |
| Fertilizer | 10 | 18.00000 | 8.00000 | 6.000–32.000 |
| Insecticide | 10 | 12.00000 | 7.48331 | 4.000–24.000 |
| Annual ratio | 10 | 0.30188 | 0.07409 | 0.150–0.400 |
Why pooling the same ten rows changes the answer
Pooled intensity = Σ fertt / Σ cornt = 180 / 570 = 0.31579
Imagine choosing a year at random. In that case, 1971 and 1980 each get a 10% weight. Instead, imagine choosing one unit from all 570 units of corn. Now 1980 accounts for 80/570 of the output, twice the weight of 1971. Because the later years generally have higher fertilizer intensity, pooling lifts the result by about 4.61% relative to the annual mean.
This distinction carries over to business data. For example, averaging store-level return rates describes the typical store when each store receives equal weight. Dividing total returns by total sales describes the return rate across purchases. Before choosing a formula, identify which unit the reader cares about.
Read a correlogram with only ten observations
proc arima data=farm;
identify var=ratio nlag=2;
run;
quit;
The ratio has a lag-one sample autocorrelation of 0.52700 and a lag-two value of 0.31758. In practical terms, higher values tend to follow higher values in this short series. However, the lag-one standard error shown in the output is about 0.316. A rough two-standard-error band around zero therefore extends to about ±0.632. With only ten years and a visible rise, a single spike offers little guidance about the best ARMA order.
The printed summary also gives two standard deviations for the same records. PROC MEANS reports 0.07409, while the ARIMA working-series summary gives 0.07029. To reconcile them, multiply 0.07409 by √(9/10). The two calculations use different divisors for the same sum of squared deviations.
Method reference · SAS/ETS guide to the ARIMA IDENTIFY statement
2. Fit corn yield and diagnose serial correlation
Suppose a farm analyst asks how corn output varies with fertilizer among years with comparable insecticide use. Multiple regression estimates that conditional association. By contrast, the intensity ratio in the first example puts fertilizer in the numerator and corn in the denominator. Its units and its economic interpretation both differ from the fertilizer slope.
proc reg data=farm;
model corn = fert insect / dw vif;
output out=farm_fit predicted=fitted residual=resid;
run;
quit;
| Term | Estimate | Standard error | Two-sided p |
|---|---|---|---|
| Intercept | 31.98067 | 1.63180 | < 0.0001 |
| Fertilizer | 0.65005 | 0.25016 | 0.0355 |
| Insecticide | 1.10987 | 0.26743 | 0.0043 |
At the 1971 input levels, the equation gives 31.98067 + 0.65005 × 6 + 1.10987 × 4 = 40.32. Actual output equals 40, so the residual is about −0.32. Likewise, the model predicts about 79.42 in 1980, against an observed 80. The residual measures the signed difference between the observation and the fitted value.
A model can fit closely even when its slopes depend on a few rows
Together, the predictors explain about 99.16% of the sample variation in corn. Yet fertilizer and insecticide have a correlation of 0.9725 across the ten years. With only two predictors, that correlation implies a variance inflation factor of about 18.46 for each slope. Thus the data contain little independent movement in one input while the other stays fixed.
| Estimation sample | Fertilizer slope | Insecticide slope |
|---|---|---|
| All ten years | 0.65005 | 1.10987 |
| Omit 1971 | 0.53832 | 1.21100 |
| Omit 1976 | 0.65005 | 1.10987 |
| Omit 1980 | 0.59751 | 1.13887 |
Why does dropping 1976 leave both slopes unchanged? That year has fertilizer of 18 and insecticide of 12, exactly the two sample means. Consequently, its centered predictor coordinates are both zero. Removing the point leaves the centered predictor cross-products and their cross-products with output unchanged. The intercept moves, however, because corn in 1976 equals 58 and the full-sample mean equals 57.
Run Durbin–Watson on the residuals from the right equation
For the corn-on-inputs regression, the Durbin–Watson statistic equals 2.114. Now fit the ratio on a constant alone. Its residuals are simply deviations from 0.30188, and DW falls to 0.2842. The first result describes errors around fitted corn output. By comparison, the second describes persistence around a fixed mean for input intensity. Reporting “the farm data have autocorrelation” would hide that distinction.
proc autoreg data=farm;
model ratio = / dw=1 dwprob;
run;
proc autoreg data=farm;
model ratio = / nlag=1 method=yw dw=1 dwprob;
run;
The Yule–Walker adjustment gives a fitted level near 0.2970 and a standard error of 0.0348. Before adjustment, the corresponding figures are 0.3019 and 0.0234. As a result, the uncertainty around the level grows by roughly 49%, even though the estimate moves by less than 0.005. The adjusted output still reports an upper-tail DW p-value of 0.0334 for negative autocorrelation. At a 5% threshold, revisit the residual pattern before using this specification for inference.
A useful cross-check comes from the supplementary test of a mean ratio of 0.25. Using independent annual observations gives t = (0.30188 − 0.25)/(0.07409/√10) ≈ 2.21 with 9 degrees of freedom. The two-sided p-value is about 0.054. Therefore even the simple test falls just above 5%. The persistence in the ratio gives another reason to treat that calculation as a classroom benchmark.
Method reference · SAS definition of Durbin–Watson and residual autocorrelation
Method reference · SAS AUTOREG and its diagnostic options
3. Compare logit and probit predictions
In the next dataset, ten countries have an event code of 1 and ten have a code of 0. The outcome is the exercise’s indicator of openness. GDP per capita is the predictor. Because the extract does not give a price base or a current currency conversion, keep the original GDP scale throughout the comparison.
data country;
input open gdpcap;
datalines;
0 569
0 408
0 2240
0 1869
1 16471
0 1282
1 2102
0 1104
0 914
1 5746
1 2173
0 978
0 762
1 12653
1 3068
1 3075
1 547
1 5185
1 7082
0 1162
;
run;
proc logistic data=country;
model open(event='1') = gdpcap / link=logit;
run;
proc logistic data=country;
model open(event='1') = gdpcap / link=probit;
run;
Specify the event explicitly so the reported probability answers your question. For example, predicting the probability of code 0 would reverse the coefficient signs. The two fitted equations below both predict code 1. Here, Φ denotes the cumulative probability under a standard normal curve.
Probit: P(open = 1 | x) = Φ(−1.99418 + 0.0010035x)
| GDP per capita | Logit | Probit | Logit minus probit |
|---|---|---|---|
| 500 | 6.3% | 6.8% | -0.52 pp |
| 1,000 | 14.1% | 16.1% | -2.02 pp |
| 2,000 | 49.7% | 50.5% | -0.85 pp |
| 3,000 | 85.6% | 84.5% | +1.07 pp |
| 4,000 | 97.3% | 97.8% | -0.55 pp |
Compare probabilities before comparing coefficients
At GDP per capita of 2,000, logit predicts 49.7% and probit predicts 50.5%. However, the raw logit slope is about 1.79 times the probit slope. Each link maps a different index onto the same probability scale. Consequently, comparing slopes directly exaggerates the practical difference near the middle of this sample.
The logit model offers another interpretation. For a 100-unit rise in GDP per capita, the estimated odds multiply by exp(100 × 0.0017958) ≈ 1.197. That implies a 19.7% increase in odds. In contrast, moving from 2,000 to 2,100 changes the estimated probability from about 49.7% to 54.1%, a rise of roughly 4.5 percentage points before rounding. Always name the starting value when reporting a probability change.
How much does the link improve fit?
The logit log-likelihood is −6.7665, compared with −6.8647 for probit. Both models fit two parameters to the same 20 rows. Therefore their AIC values, using 2k − 2ℓ, are about 17.53 and 17.73. A difference of roughly 0.20 gives little practical reason to favor either curve on fit alone. By contrast, a held-out prediction exercise would answer a different question about performance on new observations.
One country with GDP per capita of 547 has code 1, while another with 2,240 has code 0. These records explain why even a visibly rising fitted curve allows surprises. Finally, the logit slope divided by its standard error gives 0.0017958 / 0.0008999 ≈ 2.00. Squaring that unrounded ratio reproduces the printed Wald chi-square of about 3.98 and its p-value of 0.046.
Method reference · UCLA worked example of logistic regression in SAS
Method reference · UCLA guide to the probit link and SAS output
4. Estimate a money equation with instruments
Suppose GDP and money supply respond to some of the same economic shocks. Then GDP can correlate with the unobserved part of a money-supply equation. Ordinary least squares would mix that shared variation into the GDP slope. The exercise instead uses investment and government spending as instruments for GDP.
Structural equation: money = β₀ + β₁ GDP + u
In the first stage, regress GDP on the two instruments. Next, use the component of GDP that those instruments predict to estimate the structural slope. For reliable inference, let an instrumental-variable procedure calculate the second-stage standard errors. A plain regression on previously fitted GDP uses a different residual calculation.
/* Supply a table named macro with m, y, i, and g:
money, GDP, investment, and government spending. */
proc reg data=macro;
model y = i g;
test i=0, g=0;
run;
quit;
proc syslin data=macro 2sls;
endogenous y;
instruments i g;
money: model m = y;
run;
| Output item | Reported value | Interpretation |
|---|---|---|
| GDP slope | 0.115286 | A 100-unit GDP difference corresponds to 11.5286 money units in the fitted equation. |
| Slope standard error | 0.011987 | The slope divided by this value gives about 9.62. |
| Structural equation F | 92.50 | The printed table summarizes the money equation. |
| Residual degrees of freedom | 16 | With two fitted parameters, the example has 18 observations. |
| Root MSE | 92.01543 | The reported residual scale uses money units. |
The structural F of 92.50 is easy to misread. In fact, 9.62² is about 92.5 because the equation contains one slope. To assess instrument relevance, look instead at the joint test of investment and government spending in the GDP regression. The supplied output omits that first-stage statistic, so it cannot settle the strength question.
Relevance also leaves an economic question open. For example, if government spending directly changes money supply through monetary accommodation, the exclusion restriction becomes difficult to defend. Conversely, strong GDP prediction alone cannot rule out a direct monetary channel. State why each instrument should affect money only through GDP and why it should be unrelated to the money-equation shock before interpreting the slope causally.
Method reference · SAS example of two-stage least squares with PROC SYSLIN
5. Test forecast direction with six lags
Finally, ask whether past X improves a forecast of Y once past Y is already in the model. The example includes six lags of each variable and a constant. That gives 13 coefficients for 29 usable rows and leaves 16 residual degrees of freedom. Consequently, the test asks a demanding question of a small sample.
Construct lags before selecting the estimation sample
/* series must contain one row per equally spaced date. */
proc sort data=series out=ordered; by date; run;
data lagged;
set ordered;
array yl[6] y1-y6;
array xl[6] x1-x6;
y1=lag1(y); y2=lag2(y); y3=lag3(y);
y4=lag4(y); y5=lag5(y); y6=lag6(y);
x1=lag1(x); x2=lag2(x); x3=lag3(x);
x4=lag4(x); x5=lag5(x); x6=lag6(x);
if nmiss(y,x,of yl[*],of xl[*])=0;
run;
proc reg data=lagged;
model y = y1-y6 x1-x6;
test x1=0, x2=0, x3=0, x4=0, x5=0, x6=0;
model x = x1-x6 y1-y6;
test y1=0, y2=0, y3=0, y4=0, y5=0, y6=0;
run;
quit;
Sort first and inspect the calendar for gaps. Otherwise, a “one-row lag” can quietly span several years. Run each LAG call on every row before filtering so its queue advances consistently. In addition, use a common estimation sample when comparing restricted and unrestricted regressions. If the series trend or have unit roots, investigate stationarity and cointegration before relying on an ordinary levels-based F reference distribution.
| Forecast question | F(6, 16) | p-value | At 5% | At 10% |
|---|---|---|---|---|
| Does past X help predict Y? | 2.60 | 0.0596 | Fail to reject | Reject |
| Does past Y help predict X? | 0.54 | 0.7736 | Fail to reject | Fail to reject |
For the forward direction, the mean square attributable to the restrictions equals 17.71606. Divide it by the unrestricted residual mean square of 6.82435 to obtain 2.596. By comparison, the reverse test gives 3465.28866 / 6447.29086 ≈ 0.537. Neither direction clears 5%. At a prespecified 10% level, only the forward test clears the threshold.
The Y equation also reports an overall p-value of 0.0219. That test asks whether all 12 lag slopes equal zero together. However, the Granger question concerns only the six X lags after accounting for Y’s own history. Using 0.0219 to claim forward predictability at 5% would answer the wrong question.
Three different meanings of an effect over time
Suppose X rises by one unit and remains one unit higher. In the printed Y equation, X enters only through lags, so the immediate modeled response is zero. One period later, the first X slope gives −0.01778 when the two paths start with identical histories. Subsequent responses combine the remaining X coefficients with feedback from earlier changes in Y.
| Lag | Own Y slope | X slope |
|---|---|---|
| 1 | −0.73704 | −0.01778 |
| 2 | −0.82864 | −0.01157 |
| 3 | −1.16165 | −0.01493 |
| 4 | −0.67208 | −0.02471 |
| 5 | 0.26792 | 0.01126 |
| 6 | 0.09995 | 0.03078 |
Equilibrium multiplier = Σbj / (1 − Σaj) = −0.02695 / 4.03154 ≈ −0.00668
The sum −0.02695 adds the six direct lag coefficients while holding the Y terms fixed. In contrast, a cumulative six-period response also includes feedback through those Y terms. For a long-run interpretation, the dynamics must converge and the assumed permanent shift in X must make economic sense. Even then, a predictive regression alone cannot establish the impact of an intervention.
Does the published long-run multiplier actually converge?
For this conditional Y equation, we can check the convergence assumption directly. Place the six own-Y slopes in a companion matrix, or equivalently find the roots of the characteristic polynomial below. For convergence with X held fixed, every root of this particular polynomial must have magnitude below one.
# Independent numerical check in Python
import numpy as np
a = np.array([-0.73704, -0.82864, -1.16165,
-0.67208, 0.26792, 0.09995])
print(np.round(abs(np.roots(np.r_[1, -a])), 4))
# [1.1165 1.1165 0.8773 0.8773 0.3935 0.2648]
Two root magnitudes reach 1.1165. Consequently, the reported coefficients yield an algebraic equilibrium difference of −0.00668, but the conditional dynamics fail the convergence test. Reporting that number as the eventual response to a permanent change in X would give it an interpretation the fitted equation cannot support. A stability analysis of the full two-equation system would require both equations together.
Method reference · statsmodels documentation for the direction and null of the Granger test
How to audit a SAS econometrics result
| When you see… | Check first | Benchmark in this lab |
|---|---|---|
| Two different “average ratios” | Unit of weighting | 0.30188 by year, 0.31579 by corn output |
| Two different ratio SDs | Divisor n versus n − 1 | 0.07029 versus 0.07409 |
| A very high R² | Predictor overlap and sensitivity | Input correlation 0.9725 |
| Opposite binary-model signs | Which event the model predicts | Use open = 1 |
| A large F in an IV table | Which equation produced it | 92.50 belongs to the money equation |
| A different Granger decision | Test direction, lag count, and threshold | 0.0596 crosses 10% only |
When sharing a result, include the unit, sample size, equation, and comparison that produced it. For example, “Across ten years, fertilizer averaged 0.30188 units per unit of corn when every year received equal weight” gives a reader enough information to reproduce the answer. Likewise, “Six lags of X improved prediction of Y at the 10% level in 29 usable observations” makes the direction and strength of the evidence explicit.
Across these five SAS econometrics examples, the most revealing checks require only a second calculation. Divide totals, remove one year, evaluate two probabilities at the same GDP, identify the dependent variable above an F statistic, or sum six coefficients. Each check connects a line of software output to the economic question that justified running the model.
