leeper / margins

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

Error when executing cplot() in a function with function-specific data frames #156

Closed levialtringer closed 3 years ago

levialtringer commented 4 years ago

Please specify whether your issue is about:

If you are reporting (1) a bug or (2) a question about code, please supply:

Hi there! I am trying to call cplot() within a function and I am running into an error. Specifically, it seems that data frames which are generated within the function itself cannot be found. Here is a minimal example that makes use of the iris data set in R.

# example makes use of iris data set
require('datasets')

# load library
library('margins')

First, I generate a function that subsets the iris data set for specified values of "Sepal.Length", runs a simple linear regression, and returns a summary of the output. This function executes without error.

my_reg_function <- function(sepal_length_limits=NULL) {

  if (is.null(sepal_length_limits)){
    temp_df <- iris
  } else {
    temp_df <- subset(iris, Sepal.Length>=sepal_length_limits[1] & Sepal.Length<=sepal_length_limits[2])
  }

  m <- lm(Sepal.Length ~ Sepal.Width, data = temp_df)

  return(summary(m))

}

my_reg_function(sepal_length_limits = c(4,6))

Second, I generate a nearly identical function that subsets the iris data set for specified values of "Sepal.Length" and runs a simple linear regression, but now the function is written to return cplot(m).

my_cplot_function <- function(sepal_length_limits=NULL) {

  if (is.null(sepal_length_limits)){
    temp_df <- iris
  } else {
    temp_df <- subset(iris, Sepal.Length>=sepal_length_limits[1] & Sepal.Length<=sepal_length_limits[2])
  }

  m <- lm(Sepal.Length ~ Sepal.Width, data = temp_df)

  return(cplot(m))

}

my_cplot_function(sepal_length_limits = c(4,6))

Executing this function returns the following error:

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

It seems that cplot() is not able to operate on data frames that are generated within functions. Is that correct?

Running traceback() after the error is produced returns the following:

>traceback()
8: eval(model[["call"]][["data"]], env)
7: eval(model[["call"]][["data"]], env)
6: find_data.lm(object)
5: prediction::find_data(object)
4: check_factors(object, data, xvar = xvar, dx = dx)
3: cplot.lm(m)
2: cplot(m) at #11
1: my_cplot_function(sepal_length_limits = c(4, 6))

The session information for this example is:

> sessionInfo()
R version 4.0.1 (2020-06-06)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18362)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                           LC_TIME=English_United States.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.6     compiler_4.0.1    tools_4.0.1       data.table_1.12.8 prediction_0.3.14

Thank you in advance for any responses that might help me understand what's going on here!

levialtringer commented 4 years ago

RESOLVED: I resolved the error by specifying the data argument in the cplot() function. See the code below.

my_cplot_function <- function(sepal_length_limits=NULL) {

  if (is.null(sepal_length_limits)){
    temp_df <- iris
  } else {
    temp_df <- subset(iris, Sepal.Length>=sepal_length_limits[1] & Sepal.Length<=sepal_length_limits[2])
  }

  m <- lm(Sepal.Length ~ Sepal.Width, data = temp_df)

  return(cplot(m, data = temp_df))

}

my_cplot_function(sepal_length_limits = c(4,6))

I also think that the initial error is specific to Windows machines.