I am using dplyr to summarize a dataframe that contains many groups. The original data is density data over time for populations of organisms. For instance (where dots denote many more rows of data):
group | time | density |
---|---|---|
A | 0 | 0 |
A | 10 | 1 |
A | 20 | 2 |
A | 30 | 4 |
A | ... | ... |
B | 0 | 0 |
B | 10 | 2 |
B | ... | ... |
C | 0 | 0 |
... | ... | ... |
I have various other metrics I've used to summarize each group's timeseries already within a summarize call. However, I'd now like to use optim to fit mathematical models of population growth to the density data. For instance, the logistic model of the form:
density = K/(1+((K-initial_density)/initial_density)*e^(r*time))
I can do so normally (outside of summarize) by writing a function for the error (d_0 is initial density):
logis_fit_err <- function(params, t_vals, dens_vals) {
#params <- c("k" = ..., "d_0" = ..., "r" = ...)
pred_vals <- with(as.list(params),
k/(1+(k*d_0/d_0)*exp(r*t_vals)))
return(sum((log10(pred_vals) - log10(dens_vals))**2))
}
Then calling optim using that function:
my_fit <- optim(par = c("k" = 10**9, "d_0" = 0,
"r" = 0.04),
fn = logis_fit_err,
dens_vals = density,
t_vals = time,
method = "BFGS")
The results will be stored as a named vector in my_fit$par
. However, from each fit I need to extract both the r and k parameters into different columns of my summarize output
summarize(my_grouped_data,
fit_r = optim(par = c("k" = 10**9, "d_0" = 0,
"r" = 0.04),
fn = logis_fit_err,
dens_vals = density,
t_vals = time,
method = "BFGS")$par["r"],
fit_k = optim(par = c("k" = pseudo_K, "d_0" = first_min,
"r" = max_percap_gr_rate),
fn = logis_fit_err,
dens_vals = density,
t_vals = time,
method = "BFGS")$par["k"])
Naturally, though, this will run the optim algorithm once for each parameter, which is both not ideal for speed and, depending on the stochasticity of the optim solution, may give me wrong results. How can I save the r and k fit parameters from the same run of optim into different columns of the output summary dataframe?
For future readers: in the end, I decided to loop through my groups outside of the summarize statement.