Home > Software engineering >  Error when applying different sets of nls starting values for each data frame in a list
Error when applying different sets of nls starting values for each data frame in a list

Time:10-13

I am trying to fit multiple nls functions using the split-apply-combine method with an example from Apply different start parameters to model using purrr::map within dplyr::mutate

The code ran 5 years ago but doesn't run now.

library(tidyverse)

df <- data.frame(Group = c(rep("A", 7), rep("B", 7), rep("C", 7)),
                 Time = c(rep(c(1:7), 3)),
                 Result = c(100, 96.9, 85.1, 62.0, 30.7, 15.2, 9.6, 
                            ## I replaced these values!!
                            ## Group B initial values are NOT MY PROBLEM
                            105, 90, 82, 55, 40, 23, 7, 
                            100, 55.61, 3.26, -4.77, -7.21, -3.2, -5.6))

## ggplot(df, aes(x = Time, y = Result, group = Group))   geom_line()

df_p <-
  df %>%
  group_by(Group) %>%
  nest() %>% 
  ## init vals are all the same, but this shows how to make them different
  mutate(start = list(
    list(a = -3, b = 85, c = 4, d = 10),
    list(a = -3, b = 85, c = 4, d = 10),
    list(a = -3, b = 85, c = 4, d = 10))
)

Error in `mutate()`:
! Problem while computing `start = list(...)`.
✖ `start` must be size 1, not 3.
ℹ The error occurred in group 1: Group = "A".
Backtrace:
 1. df %>% dplyr::group_by(Group) %>% nest() %>% ...
 3. dplyr:::mutate.data.frame(...)

Replacing mutate( with dplyr:::mutate.data.frame( returns another error: Error: 'mutate.data.frame' is not an exported object from 'namespace:dplyr'

UPDATE I like the nest(cols = -Group), but the %>% nest %>% ungroup%>% is necessary for the subsequent steps, which are essential, to run.

df %>% 
   nest(cols = -Group) %>% 
   mutate(start = list(list(a = -3, b = 85, c = 4, d = 10),
    list(a = -3, b = 85, c = 4, d = 10),
    list(a = -3, b = 85, c = 4, d = 10))) %>%
  mutate(model = map2(data, start,
                       ~ nls(Result ~ a (b-a)/(1 (Time/c)^d),
                             data = .x, start = .y)),
    # model quality measurements
    glance = map(model, broom::glance),
    # contains parameters from model
    tidy = map(model, broom::tidy),
    # estimates and errors
    augment = map(model, broom::augment) )
Error in `mutate()`:
! Problem while computing `model = map2(...)`.
Caused by error in `purrr:::stop_bad_type()`:
! `.x` must be a vector, not a function
Backtrace:
 1. ... %>% ...
 8. purrr:::stop_bad_type(...)
 Error in mutate(., model = map2(data, start, ~nls(Result ~ a   (b - a)/(1   : 

Caused by error in `purrr:::stop_bad_type()`:
! `.x` must be a vector, not a function



df %>%
  dplyr::group_by(Group) %>%
  nest() %>% 
  ungroup %>%
  ## init vals are all the same, but this shows how to make them different
 dplyr::mutate(start = list(
    list(a = -3, b = 85, c = 4, d = 10),
     list(a = -3, b = 85, c = 4, d = 15),
     list(a = -3, b = 85, c = 4, d = 13)),
   model = map2(data, start,
                       ~ nls(Result ~ a (b-a)/(1 (Time/c)^d),
                             data = .x, start = .y)),
    # model quality measurements
    glance = map(model, broom::glance),
    # contains parameters from model
    tidy = map(model, broom::tidy),
    # estimates and errors
    augment = map(model, broom::augment))
# A tibble: 3 × 7
  Group data             start            model  glance           tidy             augment         
  <chr> <list>           <list>           <list> <list>           <list>           <list>          
1 A     <tibble [7 × 2]> <named list [4]> <nls>  <tibble [1 × 9]> <tibble [4 × 5]> <tibble [7 × 4]>
2 B     <tibble [7 × 2]> <named list [4]> <nls>  <tibble [1 × 9]> <tibble [4 × 5]> <tibble [7 × 4]>
3 C     <tibble [7 × 2]> <named list [4]> <nls>  <tibble [1 × 9]> <tibble [4 × 5]> <tibble [7 × 4]>

CodePudding user response:

It is the grouping that created the issue. We can nest without grouping

library(dplyr)
df %>% 
   nest(cols = -Group) %>% 
   mutate(start = list(list(a = -3, b = 85, c = 4, d = 10),
    list(a = -3, b = 85, c = 4, d = 10),
    list(a = -3, b = 85, c = 4, d = 10)))

-output

# A tibble: 3 × 3
  Group cols             start           
  <chr> <list>           <list>          
1 A     <tibble [7 × 2]> <named list [4]>
2 B     <tibble [7 × 2]> <named list [4]>
3 C     <tibble [7 × 2]> <named list [4]>

Or in the OP's code, just add ungroup after the nest i.e. %>% nest %>% ungroup%>% and the mutate code that follows

  • Related