For my thesis I am doing an Instrumental Variables (IV) regression and I was wondering if I did it the right way. Couple of issues I have:

  1. Comparing the linear model with the IV models, the sign of the effect changes (positive to negative or the other way round).
  2. Using Two Stage Least Squares (2SLS) with ivreg (from the AER package) gives negative R² values, so I decided to manually compute the 2SLS estimates. These give the same estimates as the ivreg code but now with statistically significant results.

I have limited data and therefore I did not expect any significant results as I already did some non-parametric tests and the means of the different groups were not significantly different.

I am researching the effect of policies of organizations on a given budget. The organization performs well if the budget residual is positive, so they have less costs than budgeted. The variable is a percentage, either positive or negative. There is non random selection into treatment as organizations can determine their own policy. Furthermore, the policy factors are mostly dummy variables, 19 variables are binary and 2 are categorical and 1 is ratio. My IV is any number between 0 and 1.

This is what I did:

1. I estimate a simple Ordinary Least Squares model to see what it would do (I know the results don't mean anything).

lm1 <- lm(budget ~ policy1, data=df)
lm2 <- lm(budget ~ policy2, data=df)

2. Then I performed an IV with the ivreg code, though the R² became

negative which I thought was weird.

ivreg1 <- ivreg(budget ~ policy1| iv, data=df)
ivreg2 <- ivreg(budget ~ policy2 | iv, data=df)
stargazer(ivreg1, ivreg2, dep.var.labels=c("Budget"), covariate.labels = c("policy 1", "policy2") , align=TRUE, column.sep.width = "-15pt", font.size = "small", type="text")

3. So I tried to do the 2SLS in steps myself.

Instead of fitted.values(reg1) I also used predict(reg1). This gives the same output.

reg1<- lm(policy1~iv)
policy1.hat <- fitted.values(reg1)
reg2 <- lm(policy2~iv)
policy2.hat <- fitted.values(reg2)
ivreg3 <- lm(budget~policy1.hat)
ivreg4 <- lm(budget~policy2.hat)
stargazer(ivreg1, ivreg2, dep.var.labels=c("Budget"), covariate.labels = c("policy 1", "policy2"), align=TRUE, column.sep.width = "-15pt", font.size = "small", type="text")

With this step I got a positive adjusted R² but I noticed that the policy factors are now significant and that the sign compared to the lm model changes.

Question: Am I computing the IV regression wrong?

Example data (not real numbers due to anonymity of data):

 df <- data.frame(
    budget = c(4,2.8,9.1,15.5,10.1,12.9,4.3,
        iv = c(0.52,0.43,0.41,0.44,0.41,0.4,0.39,
   policy1 = c(1L,1L,1L,1L,1L,1L,0L,1L,1L,1L,
   policy2 = c(1L,1L,1L,1L,1L,1L,1L,0L,0L,1L,

1 Answer 1


You do not compute the point estimates wrong, but your manual procedure of computing IV estimates in procedure 3 produces the wrong standard errors, so that you should trust the standard errors (and hence significances) of the results of ivreg. The issue is mentioned (but not fleshed out) here. It is discussed in many introductory econometrics textbooks like Wooldridge, Introductory Econometrics, though. See e.g. here.

That $R^2$ is negative for ivreg is, in turn, possible (and should hence not bother you). $R^2$ is only guaranteed to be nonnegative for least squares if the regressors contain a constant (or at least something that can be combined into a constant). That is not the case for IV regressions, which do not enforce the orthogonality between regressors and IV residuals.

  • $\begingroup$ Thank you for your response! Your answer makes things much clearer now. Thank you! $\endgroup$
    – es_dutch
    May 29, 2020 at 13:20
  • $\begingroup$ Excellent! In case you plan to be around this site more often, you may want to note that clicking on the check sign next to the answer amounts to telling the community that the question has been dealt with. $\endgroup$ May 29, 2020 at 15:38
  • $\begingroup$ okay, thanks for the tip. I will do that! $\endgroup$
    – es_dutch
    May 29, 2020 at 18:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.