0

I am fitting an elastic net with cross-validation and I am looking at how big the coefficients are for each predictor:

lambda <- cv.glmnet(x = features_training, y = outcomes_training, alpha = 0)
elnet <- lambda$glmnet.fit
coefs <- coef(elnet, s = lambda$lambda.min, digits = 3)

The coefs variable contains a dgCMatrix:

                           1
(Intercept)    -1.386936e-16
ret             4.652863e-02
ind30          -2.419878e-03
spyvol          1.570406e-02

Is there a quick way to turn this into a dataframe with 2 columns (one for the predictor name and the other for the coefficient value)? as.data.frame, as.matrix or chaining both did not work. I would notably like to sort the rows according to the second column.

Ben
  • 429
  • 4
  • 11
  • There's a `broom::tidy` method for `dgCMatrix`, e.g. `mod <- glmnet::cv.glmnet(model.matrix(~ ., mtcars[-1]), mtcars$mpg, alpha = 0); broom::tidy(coef(mod$glmnet.fit, s = mod$lambda.min, digits = 3))` – alistaire Dec 24 '17 at 05:16

2 Answers2

2

broom::tidy has a nice method for coercing dgCMatrix objects to long-form data frames (a bit like as.data.frame.table), which works well here:

mod <- glmnet::cv.glmnet(model.matrix(~ ., mtcars[-1]), mtcars$mpg, alpha = 0)

broom::tidy(coef(mod$glmnet.fit, s = mod$lambda.min, digits = 3))
#>            row column        value
#> 1  (Intercept)      1 21.171285892
#> 2          cyl      1 -0.368057153
#> 3         disp      1 -0.005179902
#> 4           hp      1 -0.011713150
#> 5         drat      1  1.053216800
#> 6           wt      1 -1.264212476
#> 7         qsec      1  0.164975032
#> 8           vs      1  0.756163432
#> 9           am      1  1.655635460
#> 10        gear      1  0.546651086
#> 11        carb      1 -0.559817882
alistaire
  • 42,459
  • 4
  • 77
  • 117
1

Another way, and no hacks through attributes() function, but extracting the rownames and matrix values. The attributes(class(coefs)) informs that dgCMatrix is a sparse matrix created using Matrix package.

data.frame( predict_names = rownames(coefs),
            coef_vals = matrix(coefs))

# predict_names    coef_vals
# 1    (Intercept) 21.117339411
# 2    (Intercept)  0.000000000
# 3            cyl -0.371338786
# 4           disp -0.005254534
# 5             hp -0.011613216
# 6           drat  1.054768651
# 7             wt -1.234201216
# 8           qsec  0.162451314
# 9             vs  0.771959823
# 10            am  1.623812912
# 11          gear  0.544171362
# 12          carb -0.547415029
Sathish
  • 12,453
  • 3
  • 41
  • 59