2

I have used nlme to fit and compare nonlinear models in the past. I would now like to use it to fit models to data that are grouped by more than one identifier. It would be great if I could integrate dplyr, purrr, and nlme. One of the nice things would be using the self starting functions that are in the nlme package. I also have a lot of models to run. I'm just not sure if it will all fit together.

Current nlme situation. This works, but limited to only one grouping variable:

library(tidyverse)
library(nlme)
diamonds_grouped <- groupedData(price ~ carat | cut, data = diamonds)
nlsList(price ~ SSlogis(carat, Asym, xmid, scal), data = diamonds_grouped)  

Desired sort of workflow. Doesn't work, just how far I've gotten:

fit_mod <- function(df) {  ### Not much faith in how I wrote this function
  nlsList(price ~ SSlogis(carat, Asym, xmid, scal), data = .)
} 

diamonds %>%
group_by(cut, color) %>%
nest() %>%
mutate(
  model = map(data, fit_mod),
  tidied = map(model, tidy)
)

Not meant to be, or I just don't know how to do it?

Nazer
  • 3,654
  • 8
  • 33
  • 47

2 Answers2

1

You could modify your function to include grouped Data for each subset

library(tidyverse)
library(nlme)

fit_mod <- function(df) {  
  diamonds_grouped <- groupedData(price ~ carat | cut, data = df)
  nlsList(price ~ SSlogis(carat, Asym, xmid, scal), data = diamonds_grouped)
} 

and then split the data and apply fit_mod for each subset

diamonds %>% group_split(cut, color) %>%  map(fit_mod)

#[[1]]
#Call:
#  Model: price ~ SSlogis(carat, Asym, xmid, scal) | cut 
#   Data: diamonds_grouped 

#Coefficients:
#         Asym     xmid      scal
#Fair 16928.32 1.410986 0.4113035

#Degrees of freedom: 163 total; 160 residual
#Residual standard error: 1449.725

#[[2]]
#Call:
#  Model: price ~ SSlogis(carat, Asym, xmid, scal) | cut 
#   Data: diamonds_grouped 

#Coefficients:
#         Asym     xmid      scal
#Fair 16565.84 1.409934 0.3833443

#Degrees of freedom: 224 total; 221 residual
#Residual standard error: 1175.058
#.....
#.....

Also I think you cannot apply tidy function to model of class nlsList.

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • 1
    `nlsList` tidier is in [another package](https://cran.r-project.org/web/packages/nlshelper/index.html). Doing `library(nlshelper); broom::tidy(myModel)` should work. – Artem Sokolov Dec 02 '19 at 16:03
1

One option is to introduce a new variable that captures all possible groupings across multiple variables. Using your example:

diamonds2 <- diamonds %>% mutate( grp = str_c(cut, "_", color) )
diamonds2_grp  <- groupedData( price ~ carat | grp, data = diamonds2 )
nlsList(price ~ SSlogis(carat, Asym, xmid, scal), data = diamonds2_grp )

# Call:
#   Model: price ~ SSlogis(carat, Asym, xmid, scal) | grp 
#    Data: diamonds2_grp 
# 
# Coefficients:
#                 Asym     xmid      scal
# Fair_E      16565.84 1.409934 0.3833443
# Fair_D      16928.32 1.410986 0.4113035
# Fair_F      13905.28 1.335952 0.3877184
# Good_E      15894.55 1.253196 0.3245564
# Fair_I      17427.69 1.783398 0.5071487
# Good_J      17233.34 1.676204 0.4604250
# ...
Artem Sokolov
  • 13,196
  • 4
  • 43
  • 74