# Constructing the OLS standard error by hand to avoid regression

I am having trouble deriving the standard error of a simple regression estimator by hand. Stata code and output for a toy example using the cars dataset is below.

The basic idea is that I have a binary treatment that interacts with a binary covariate. All observations are independent. I'm probably overlooking something simple.

My outcome is a weighted average of the effects in the two groups: $$TE= \frac{N_1 \cdot \delta_1 + N_2 \cdot \delta_2}{N_1+N_2}=\frac{N_1 \cdot (\bar X_{T_1}-\bar X_{C_1}) + N_2 \cdot (\bar X_{T_2}-\bar X_{C_2})}{N_1+N_2},$$ where $N_i=T_i+C_i$ is the number of people in group $i$ and $\delta_i$ is the effect of treatment in group $i$. I will estimate the $\delta$s with the group-specific difference in sample means. My manual calculation agrees with the regression output below.

Using the standard sum of weighed random variables, I get $$Var[TE]= \left(\frac{N_1}{N_1+N_2}\right)^2 \cdot \left[ \frac{\sigma^2_{T_1}}{N_{T_1}}+\frac{\sigma^2_{C_1}}{N_{C_1}}\right] +\left(\frac{N_2}{N_1+N_2}\right)^2 \cdot\left[ \frac{\sigma^2_{T_2}}{N_{T_2}}+\frac{\sigma^2_{C_2}}{N_{C_2}}\right],$$

This is the quantity that I am having trouble scaling to get the standard error. My intuition is that the delta method used by Stata is using the covariance terms, whereas I am dropping them by assumption. Is there a way to get the OLS standard error without using OLS? I am trying to avoid running a regression.

Here's my code and output:

. /* Make Fake Data */
. sysuse auto, clear
(1978 Automobile Data)

. rename foreign treat

. label define treat 0 "C" 1 "T"

. lab val treat treat

. gen group=cond(weight>3000,1,0)

. sum group, meanonly

. local mean = r(mean)

. /* Get Summary Stats */
. table treat group, c(mean price sd price freq) format(%9.3fc) // use 3 SDs to match the margins output

--------------------------------
|        group
Car type |         0          1
----------+---------------------
C | 4,183.800  6,838.081
|   743.072  3,359.359
|    15.000     37.000
|
T | 5,773.900  12492.500
| 1,803.450    703.571
|    20.000      2.000
--------------------------------

. /* Regression Treatment Effects */
. reg price ib(0).treat##ib(0).group

Source |       SS       df       MS              Number of obs =      74
-------------+------------------------------           F(  3,    70) =    7.78
Model |   158773405     3  52924468.2           Prob > F      =  0.0001
Residual |   476291991    70  6804171.31           R-squared     =  0.2500
Total |   635065396    73  8699525.97           Root MSE      =  2608.5

------------------------------------------------------------------------------
price |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
treat |
T  |     1590.1   890.9658     1.78   0.079    -186.8752    3367.075
1.group |   2654.281   798.4409     3.32   0.001     1061.841    4246.721
|
treat#group |
T#1  |   4064.319   2092.798     1.94   0.056    -109.6345    8238.272
|
_cons |     4183.8   673.5068     6.21   0.000     2840.533    5527.067
------------------------------------------------------------------------------

. lincom 1.treat + 1.treat#1.group*mean'

( 1)  1.treat + .527027*1.treat#1.group = 0

------------------------------------------------------------------------------
price |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
(1) |   3732.106   1083.335     3.45   0.001     1571.463    5892.748
------------------------------------------------------------------------------

. margins, dydx(treat)

Average marginal effects                          Number of obs   =         74
Model VCE    : OLS

Expression   : Linear prediction, predict()
dy/dx w.r.t. : 1.treat

------------------------------------------------------------------------------
|            Delta-method
|      dy/dx   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
treat |
T  |   3732.106   1083.335     3.45   0.001     1571.463    5892.748
------------------------------------------------------------------------------
Note: dy/dx for factor levels is the discrete change from the base level.

. /* By Hand */
. di "E[TE] =  "((15+20)*(5773.9 - 4183.8)  + (37+2)*(12492.5 - 6838.081))/(15 + 37 + 20 + 2)
E[TE] =  3732.106

. di "SE[TE] = "sqrt( (15+20)^2*((743.072^2)/15 + (1803.45^2)/20 )/(15+37+20+2)^2 + (37+2)^2*((3359.359^2)/37+(703.571^2)/2)/(15+37+20+2)^2)/sqrt(4)
SE[TE] = 222.53007


Here's just the code in case someone wants to cut n' paste:

/* Make Fake Data */
sysuse auto, clear
rename foreign treat
label define treat 0 "C" 1 "T"
lab val treat treat

gen group=cond(weight>3000,1,0)
sum group, meanonly
local mean = r(mean)

/* Get Summary Stats */
table treat group, c(mean price sd price freq) format(%9.3fc) // use 3 SDs to match the margins output

/* Regression Treatment Effects */
reg price ib(0).treat##ib(0).group
lincom 1.treat + 1.treat#1.group*mean'
margins, dydx(treat)

/* By Hand */
di "E[TE] =  "((15+20)*(5773.9 - 4183.8)  + (37+2)*(12492.5 - 6838.081))/(15 + 37 + 20 + 2)
di "SE[TE] = "sqrt( (15+20)^2*((743.072^2)/15 + (1803.45^2)/20 )/(15+37+20+2)^2 + (37+2)^2*((3359.359^2)/37+(703.571^2)/2)/(15+37+20+2)^2)/sqrt(4)

• What is the formula for Var[TE] that you are trying to reproduce? Where is it coming from? – StasK Oct 22 '13 at 15:24
• I derived it using the familiar sum of two weighted variables variance formula, but I must be missing a $N^{.5}$in the denominator. – Dimitriy V. Masterov Oct 22 '13 at 15:30
• Each treatment control difference is an RV, the covariances are zero, I am allowing for unequal variances in each of the groups. – Dimitriy V. Masterov Oct 22 '13 at 15:35