araspion
araspion

Reputation: 713

R function not properly taking felm object as argument

I'm trying to write an R function that takes a felm object as an argument. The function doesn't seem to recognize the felm object inside the function, however, if I run the code outside of a function, it works fine. Can someone help me understand why this doesn't work? Thanks! Reproducible example below.

library(sandwich)
library(lfe)
set.seed(2020)
x <- rnorm(1000)
x2 <- rnorm(length(x))
y <- x + 0.5*x2
adj_test <- diag(1, 1000, 1000)
test_felm <- felm(y ~ x + x2 | 0 | 0 | 0)

vcov.adjacency.robust <- function(felm_object, adjacency.matrix, estfunc=sandwich::estfun) {
  eef <- estfunc(felm_object)

  N <- nrow(adjacency.matrix)
  m <- crossprod(eef, adjacency.matrix %*% eef)

  sandwich(felm_object, meat = as.matrix(m) / N)
}

vcov.adjacency.robust(test_felm, adj_test)
Error in model.matrix(x) : object 'felm_object' not found 
eef <- sandwich::estfun(test_felm)
N <- nrow(adj_test)
m <- crossprod(eef, adj_test %*% eef)
sandwich(test_felm, meat = as.matrix(m) / N)

             (Intercept)            x           x2
(Intercept) 2.772862e-33 2.615412e-34 2.335601e-35
x           2.615412e-34 7.750617e-33 7.657461e-34
x2          2.335601e-35 7.657461e-34 2.947959e-33

Upvotes: 3

Views: 160

Answers (1)

jay.sf
jay.sf

Reputation: 72663

sandwich::estfun is calling a method,

sandwich::estfun
# function (x, ...) 
# {
#   UseMethod("estfun")
# }
# <bytecode: 0x00000000142bb260>
#   <environment: namespace:sandwich>

and the method doesn't seem to be acessible within the function. So calling the right function directly, which is sandwich:::estfun.lm, fixes the problem.

vcov.adjacency.robust <- function(felm_object, adjacency.matrix, 
                                  estfunc=sandwich:::estfun.lm) {
  eef <- estfunc(felm_object)
  N <- nrow(adjacency.matrix)
  m <- crossprod(eef, adjacency.matrix %*% eef)
  sandwich(felm_object, meat = as.matrix(m) / N)
}

(res <- vcov.adjacency.robust(test_felm, adj_test))
#              (Intercept)            x           x2
# (Intercept) 2.772862e-33 2.615412e-34 2.335601e-35
# x           2.615412e-34 7.750617e-33 7.657461e-34
# x2          2.335601e-35 7.657461e-34 2.947959e-33

eef <-  estfun(test_felm)
N <- nrow(adj_test)
m <- crossprod(eef, adj_test %*% eef)
check <- sandwich(test_felm, meat = as.matrix(m) / N)

stopifnot(all.equal(res, check))

Upvotes: 1

Related Questions