'Penalized logistic regression with grouped data

My data is a collection of x values (shift.magnitude) and y values (response.sign) for each of a large collection of participants specified by ID. I am performing logistic regression for each participant separately using this command:

  do(fitmod = tidy(glm(response.sign~shift.magnitude,family=binomial(link="logit"), data = .))) %>% 
  unnest(fitmod) %>%
  pivot_wider(id_cols = ID, names_from = term, values_from = c(estimate))

I want to turn this into a ridge regression using the glmnet package, but I can't figure out how to adapt this command to work with glmnet. I added a column of ones to the data since glmnet won't work with a single predictor, but I'm left with the problem that when I try to make the x vector with the code

x <- model.matrix(response.sign~shift.magnitude+ones, ID_grouped)[,-1]

it is no longer in a grouped form. How can I adapt this grouped operation to glmnet?



Solution 1:[1]

What about wrapping your glmnet call in a function and calling that function on each group using map()?

f <- function(x,y, alpha=0) {
  x=model.matrix(y~x)
  glmnet(x,y, family="binomial", alpha=alpha)
}

df %>% 
  nest(data=-ID) %>% 
  mutate(fitmod = map(data, ~f(.x$shift.magnitude, .x$response.sign)))

This will return a nested frame with model for each group, which you can then manipulate with unnest(),etc.

Output:

      ID data              fitmod  
   <int> <list>            <list>  
 1    12 <tibble [47 x 2]> <lognet>
 2     7 <tibble [55 x 2]> <lognet>
 3    13 <tibble [47 x 2]> <lognet>
 4     9 <tibble [54 x 2]> <lognet>
 5    14 <tibble [45 x 2]> <lognet>
 6     6 <tibble [45 x 2]> <lognet>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 langtang