leeper / margins

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

cplot not working with logical variables in model? #142

Open nowo1978 opened 4 years ago

nowo1978 commented 4 years ago

Please specify whether your issue is about:

Hi! I am using margins to estimate marginal effects and cplot() to plot predicted probabilities. But if there is a logical variable "x" in my model cplot() returns the error:

Error in eval(predvars, data, env) : object 'x' not found

Here is a minimal code example:

library("margins")

cars <- mtcars
cars$am <- as.logical(cars$am)

reg <- lm(hp ~ disp + am, data = cars)

cplot(reg, x = "disp")
Error in eval(predvars, data, env) : object 'am' not found

It works okay if I use the same command with the "what" argument:

cplot(reg, x = "disp", what = "effect")

Which is why I think it is a bug rather than an error on my side. It also works fine if I use the original numeric variable or if it is defined as a factor.

Thanks for your work! Klaus

Session info and traceback:

> traceback()
10: eval(predvars, data, env)
9: eval(predvars, data, env)
8: model.frame.default(Terms, newdata, na.action = na.action, xlev = object$xlevels)
7: model.frame(Terms, newdata, na.action = na.action, xlev = object$xlevels)
6: predict.lm(model, newdata = datalist, type = type, se.fit = TRUE, 
       ...)
5: predict(model, newdata = datalist, type = type, se.fit = TRUE, 
       ...)
4: prediction.lm(model = object, data = tmpdat, type = type, level = level)
3: prediction(model = object, data = tmpdat, type = type, level = level)
2: cplot.lm(reg, x = "disp")
1: cplot(reg, x = "disp")
> sessionInfo()
R version 3.6.3 (2020-02-29)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18363)

Matrix products: default

locale:
[1] LC_COLLATE=German_Austria.1252  LC_CTYPE=German_Austria.1252   
[3] LC_MONETARY=German_Austria.1252 LC_NUMERIC=C                   
[5] LC_TIME=German_Austria.1252    

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

other attached packages:
[1] margins_0.3.23

loaded via a namespace (and not attached):
[1] MASS_7.3-51.5     compiler_3.6.3    tools_3.6.3       data.table_1.12.8
[5] prediction_0.3.14
vincentarelbundock commented 4 years ago

I believe that this is due to 2 problems:

  1. Bug in cplot_extract.default where the function calls an undefined object called "dat" when it should be "data".
  2. The prediction::mean_or_mode does not have a method to handle logical data.

To illustrate, I added a logical method to a branch of my prediction fork, and I fixed the bug in my marginsplot package. marginsplot was initially intended to be a ggplot2 replacement for margins' plotting functions. Unfortunately, it looks like the maintainer of margins no longer has time to look at contributions, so it sat in a PR for a year. I spun it off as a separate package until an opportunity for merging comes up.

You can try my fix like this:

remotes::install_github('vincentarelbundock/marginsplot')
remotes::install_github('vincentarelbundock/prediction@mean_mode_logical')

## load package
library("margins")
library("marginsplot")

cars <- mtcars
cars$am <- as.logical(cars$am)
mod <- lm(hp ~ disp + am, data = cars)
cplot(mod, x = "disp")

Created on 2020-05-29 by the reprex package (v0.3.0)