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