margins package returning error Error in eval(model[["call"]][["data"]], env) : object '.' not found

Viewed 105

I'm trying to use the margins package to get marginal effects of a simple linear model, but it returns the error:

Error in eval(model[["call"]][["data"]], env) : object '.' not found

This data can be used to reproduce the problem:

forty_rows <- structure(list(wk_dist_eff_nov16 = structure(c(18, -24, -35, 
-30, 18, 18, 4, -56, -41, 31, 18, -20, 36, 18, -15, 18, 35, 18, 
18, -58, -52, -21, -47, 19, 18, 23, -38, 4, -50, -63, 31, -2, 
-27, 2, 18, 18, -8, -12, 14, 19), class = "difftime", units = "days"), 
    election_2016_11 = c(NA, NA, "0", NA, "0", "0", "1", NA, 
    NA, "0", "0", NA, "1", "0", "0", "0", "1", "0", "0", NA, 
    NA, "0", "0", "0", "1", "1", "1", "1", NA, NA, "0", NA, "0", 
    NA, "1", "0", NA, NA, "0", "1")), class = "data.frame", row.names = c(NA, 
-40L))

library(tidyverse)

model <- forty_rows %>% 
             filter(!is.na(election_2016_11), 
                    wk_dist_eff_nov16 %in% -36:0) %>% 
    lm(as.numeric(election_2016_11) ~ as.factor(wk_dist_eff_nov16), data = .)

Which returns kind of non-sensical values but that's just an artefact of how i've created a small reproducible example (sampling only 40 rows from a df of > 500k). I can then call tidy() on model object no problem, but margins() returns the error:

tidy(model)
# A tibble: 4 x 5
  term                            estimate std.error statistic p.value
  <chr>                              <dbl>     <dbl>     <dbl>   <dbl>
1 (Intercept)                            0       NaN       NaN     NaN
2 as.factor(wk_dist_eff_nov16)-27        0       NaN       NaN     NaN
3 as.factor(wk_dist_eff_nov16)-21        0       NaN       NaN     NaN
4 as.factor(wk_dist_eff_nov16)-15        0       NaN       NaN     NaN

library(margins)
margins(model)
Error in eval(model[["call"]][["data"]], env) : object '.' not found

Does anyone know what's going wrong here? And how I can fix it?

2 Answers

margins internally uses some find_data(model, parent.frame()) stuff to find the data and finds just . due to piping.

You may try to explicitly define the data which can be found in model$model.

library(dplyr)

model <- mtcars %>%
  mutate(foo='bar') %>%
  lm(mpg ~ hp, data=.)

margins(model)  
# Error in eval(model[["call"]][["data"]], env) : object '.' not found

margins(model, data=model$model)  
#       hp
# -0.06823

Works with mtcars but not with your example data though.

You may want to try the marginaleffects package, which is designed as a “spiritual successor” to margins, and is actively maintained (disclaier: I am the author):

library(tidyverse)
library(marginaleffects)

forty_rows <- structure(list(wk_dist_eff_nov16 = structure(c(18, -24, -35, 
-30, 18, 18, 4, -56, -41, 31, 18, -20, 36, 18, -15, 18, 35, 18, 
18, -58, -52, -21, -47, 19, 18, 23, -38, 4, -50, -63, 31, -2, 
-27, 2, 18, 18, -8, -12, 14, 19), class = "difftime", units = "days"), 
    election_2016_11 = c(NA, NA, "0", NA, "0", "0", "1", NA, 
    NA, "0", "0", NA, "1", "0", "0", "0", "1", "0", "0", NA, 
    NA, "0", "0", "0", "1", "1", "1", "1", NA, NA, "0", NA, "0", 
    NA, "1", "0", NA, NA, "0", "1")), class = "data.frame", row.names = c(NA, 
-40L))

model <- forty_rows %>% 
             filter(!is.na(election_2016_11), 
                    wk_dist_eff_nov16 %in% -36:0) %>% 
    lm(as.numeric(election_2016_11) ~ as.factor(wk_dist_eff_nov16), data = .)
mfx <- marginaleffects(model)

As you noted, the results of this model are non-sensical, and the coefficients zero, so marginaleffects does not calculate cannot standard errors, but it doesn’t seem to error. Perhaps it will work in your real data. If it doesn’t, feel free to file a report on Github.

Related