parsnip icon indicating copy to clipboard operation
parsnip copied to clipboard

Setting `relax = TRUE` for glmnet models fails

Open hfrick opened this issue 4 months ago • 0 comments

Following on from https://github.com/tidymodels/poissonreg/issues/82:

This affects all glmnet models we wrap in tidymodels (not just here in poissonreg) where we set relax = TRUE. Here is an example with linear_reg() and main arguments and engine arguments, respectively.

library(parsnip)

mod <- linear_reg(penalty = 0.5, mixture = 1) %>%
  set_engine("glmnet", relax = TRUE) %>% 
  fit(mpg ~ ., data = mtcars)
#> Error in `glmnet::glmnet()`:
#> ! Base operators are not defined for quosures. Do you need to unquote
#>   the quosure?
#> 
#> # Bad: myquosure > rhs
#> 
#> # Good: !!myquosure > rhs


mod <- linear_reg(penalty = 0.5) %>%
  set_engine("glmnet", relax = TRUE, maxit = 1000) %>% 
  fit(mpg ~ ., data = mtcars)
#> Warning: from glmnet C++ code (error code -63); Convergence for 63th lambda
#> value not reached after maxit=1000 iterations; solutions for larger lambdas
#> returned
#> Error in elnet(xd, is.sparse, y, weights, offset, type.gaussian, alpha, : 'language' object cannot be coerced to type 'integer'

Created on 2024-02-16 with reprex v2.1.0

This is because glmnet::glmnet() calls glmnet::relax.glmnet() with the "regular" fit object (glmnet code snippet).

glmnet::relax.glmnet() uses that fit object to refit without any regularization . That happens via stats::update.default() (glmnet code snippet) which uses eval() to evaluate the call -- but that call contains the arguments as quosures. That is what ultimately breaks eval().

hfrick avatar Feb 16 '24 17:02 hfrick