leeper / margins

An R Port of Stata's 'margins' Command
https://cloud.r-project.org/package=margins
Other
260 stars 39 forks source link

How to get margins for an "lm" model built inside a function? #160

Closed dfrankow closed 3 years ago

dfrankow commented 3 years ago

I have:

I don't know how to get margins for an lm model built inside a function, because model$call$data goes out of scope, so find_data cannot find the data. I believe the relevant prediction code is here.

Suggestions?

My code:

## load package
library("margins")

the_df <- data.frame(x=c(1,2,3), y=c(5,9,10))
model <- lm(y~x, data=the_df)
# works:
margins(model)
# Average marginal effects
# lm(formula = y ~ x, data = the_df)
# 
#    x
#  2.5

compute_lm <- function(df) {
  lm(y~x, data=df)
}
model <- compute_lm(the_df)
# Doesn't work:
margins(model)
# Error in data[[variable]] : object of type 'closure' is not subsettable

## session info for your system
> sessionInfo()

R version 3.6.3 (2020-02-29)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.6

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] margins_0.3.23   conflicted_1.0.4

loaded via a namespace (and not attached):
 [1] MASS_7.3-51.6     compiler_3.6.3    tools_3.6.3       rstudioapi_0.11  
 [5] crayon_1.3.4      memoise_1.1.0     data.table_1.12.8 digest_0.6.25    
 [9] rlang_0.4.7       prediction_0.3.16
dfrankow commented 3 years ago

Here is a workaround, but it feels weird.

> model$call$data <- the_df
> margins(model)
Average marginal effects
lm(formula = y ~ x, data = structure(list(x = c(1, 2, 3), y = c(5, 9, 10)), class = "data.frame", row.names = c(NA, -3L)))

   x
 2.5
leeper commented 3 years ago

Alternatively, you can set the data argument to margins() explicitly.