Tomas
Tomas

Reputation: 288

Fitted values from the ivreg {AER} object do not match manual 2SLS results

I'm trying to find out why fitted values from the ivreg estimation {AER} differ from manually performed 2-stage least squares (and from the appropriate reduced form equation)... the help for ivreg and ivreg.fit states that it invokes lm() repeatedly. I provide example from the {AER} package with fitted values calculated.

rm(list = ls())
require('AER') # install.packages('AER')
## data and example adapted from the AER package
data("CigarettesSW")
CigarettesSW$rprice <- with(CigarettesSW, price/cpi)
CigarettesSW$rincome <- with(CigarettesSW, income/population/cpi)
CigarettesSW$tdiff <- with(CigarettesSW, (taxs - tax)/cpi)

## Estimation by IV: log(rprice) is endogenous, tdiff is IV for log(rprice):
fm <- ivreg(log(packs) ~ log(rprice) + log(rincome) | log(rincome) + tdiff,
            data = CigarettesSW)
## 
##
# Reduced form for log(rprice)
rf.rprice <- lm(log(rprice) ~ log(rincome) + tdiff,
                data = CigarettesSW)
# Reduced form for log(packs)
rf.lpacks <- lm(log(packs) ~ log(rincome) + tdiff,
                data = CigarettesSW)
# "Manual" 2SLS estimation of the "fm" equation
m2sls <- lm(log(packs) ~ rf.rprice$fitted.values + log(rincome),
            data = CigarettesSW)
# Coefficients of "m2sls" are matched to "fm" object:
summary(m2sls)
summary(fm)
#
# It is my understanding, that fitted values from ivreg-fitted object "fm",
# manually performed 2SLS (in "m2sls") and from the reduced form rf.lpacks
# should be the same:
#
head(fm$fitted.values, 10)
head(m2sls$fitted.values, 10)
head(rf.lpacks$fitted.values, 10)
#
# However, fitted values from ivreg are different.

Most probably, I'm missing something obvious, but I'm stuck anyway. Would greatly appreciate any comments.

Upvotes: 4

Views: 2720

Answers (2)

jsl2
jsl2

Reputation: 43

With ivreg, you have to include your other RHS variables both in front of the "|" and afterwards.

For example:

stage1<-predict(lm(endogenous.var~x1+x2+instrument,data=data))
data$stage1<-stage1
stage2<-lm(dependent~x1+x2+stage1,data=data)

does not give you the same coefficients as

iv.model<-ivreg(dependent~x1+x2+endogenous|instrument,data=data)

It will, however, give you the same answer as

iv.model<-ivreg(dependent~x1+x2+endogenous|instrument+x1+x2,data=data. 

Live example:

rm(list=ls())

library(AER)
data(mtcars)

#let cyl be an instrument for hp
stage1<-predict(lm(hp~cyl+disp,data=mtcars))

mtcars$stage1<-stage1

stage2<-lm(mpg~stage1+disp,data=mtcars)

#this is not the same as 
ivreg.bad<-ivreg(mpg~hp|cyl+disp,data=mtcars)

#and this doesn't even work
ivreg.bad2<-ivreg(mpg~disp+hp|cyl,data=mtcars)

#but it is the same as 
ivreg.good<-ivreg(mpg~disp+hp|cyl+disp,data=mtcars)

summary(stage2)
summary(ivreg.good)
summary(ivreg.bad)

Note of course this just refers to the coefficients. The standard errors will be different as ivreg automatically applies the appropriate adjustment.

Upvotes: 1

Achim Zeileis
Achim Zeileis

Reputation: 17193

The predict() and the fitted() methods for ivreg objects simply compute x %*% b where x is the original regressor matrix and b is the vector of coefficients (estimated by IV). Thus:

x <- model.matrix(~ log(rprice) + log(rincome), data = CigarettesSW)
b <- coef(m2sls)

And then the fitted values from your manual computation are:

head(drop(x %*% b))
##        1        2        3        4        5        6 
## 4.750353 4.751864 4.720216 4.778866 4.919258 4.596331 

which exactly matches the computations from ivreg:

head(fitted(fm))
##        1        2        3        4        5        6 
## 4.750353 4.751864 4.720216 4.778866 4.919258 4.596331 

Upvotes: 3

Related Questions