Search code examples
rlinear-regressionformulaglmnet

Extract Formula From RIDGE, LASSO, and Net Elastic Regression with Coefficients (R) for many variables


I am trying to modify some code that I found in one of the answers on this post:

Extract Formula From lm with Coefficients (R)

AlexB provided these wonderful lines of code:

get_formula <- function(model) {
  broom::tidy(model)[, 1:2] %>%
    mutate(sign = ifelse(sign(estimate) == 1, ' + ', ' - ')) %>% #coeff signs
    mutate_if(is.numeric, ~ abs(round(., 2))) %>% #for improving formatting
    mutate(a = ifelse(term == '(Intercept)', paste0('y ~ ', estimate), paste0(sign, estimate, ' * ', term))) %>%
    summarise(formula = paste(a, collapse = '')) %>%
    as.character
}

Though this works for some of my code, I am having issues adapting it to print formulas from glmnet models using RIDGE, LASSO, and Net Elastic Regression.

Attached below is an example of what I am trying to provide:

library(caret)
library(glmnet)
library(mlbench)
library(psych)
data("BostonHousing")
data <- BostonHousing
set.seed(23)
ind <- sample(2, nrow(data), replace = T, prob = c(0.7, 0.3))
train <- data[ind==1,]
test <- data[ind==2,]
custom <- trainControl(method = "repeatedcv",number = 10,repeats = 5,verboseIter = T)
set.seed(23)
ridge <- train(medv~., train,method = "glmnet",tuneGrid = expand.grid(alpha = 0,lambda = seq(0.0001,1,length = 5)),trControl = custom)
ridge
coef(ridge$finalModel, ridge$bestTune$lambda) # the coefficient estimates

get_formula <- function(model) {
  broom::tidy(model)[, 1:2] %>%
    mutate(sign = ifelse(sign(estimate) == 1, ' + ', ' - ')) %>% #coeff signs
    mutate_if(is.numeric, ~ abs(round(., 2))) %>% #for improving formatting
    mutate(a = ifelse(term == '(Intercept)', paste0('y ~ ', estimate), paste0(sign, estimate, ' * ', term))) %>%
    summarise(formula = paste(a, collapse = '')) %>%
    as.character
}
get_formula(ridge$finalModel)

However, given that it is not in the same format as in the previous post, I am having issues modifying the function so that it can print out the equations I am looking for.

gives error :

Error: Problem with `mutate()` input `sign`.
x object 'estimate' not found
i Input `sign` is `ifelse(sign(estimate) == 1, " + ", " - ")`.
Run `rlang::last_error()` to see where the error occurred. 

Thank kindly for the help.


Solution

  • With minor updates, you can get the equation of a ridge regression, as follows:

    as.matrix(coef(ridge$finalModel, ridge$bestTune$lambda)) %>%
      as.data.frame() %>%
      tibble::rownames_to_column('term') %>%
      rename(estimate = 2) %>%
      mutate(sign = ifelse(sign(estimate) == 1, ' + ', ' - ')) %>% #coeff signs
      mutate(across(where(is.numeric), ~abs(round(., 2)))) %>% #for improving formatting
      mutate(a = ifelse(term == '(Intercept)', paste0('y ~ ', estimate), paste0(sign, estimate, ' * ', term))) %>%
      summarise(formula = paste(a, collapse = ''))