Я хотел бы создать обертку для функции нелинейного наименьшего квадрата Levenberg-Marquardt nls.lm
(библиотека minpack.lm), аналогичную nls2
(библиотека nls2), чтобы дать метод грубой силы для оценки соответствия модели наблюдаемым данным.R - Использование вложенных данных для запуска функции с различными наборами параметров
Идея заключается в том, чтобы создать диапазон стартовых комбинаций значений и либо:
- передать их в функцию, а затем сравнить выходную функцию для наблюдаемых данных для создания 2 значения в R^для каждого из начинать комбинации значений и запускать nls.lm с лучшим из них.
или
- запустить nls.lm на всех комбинациях и выбрать лучший возвращенное подгонку.
Я хотел бы сделать это без зацикливания и после того, как вдохновения из here пытается использовать вложенные dataframes, с одной колонкой для ввода списка параметров, по одному для значений, возвращаемых моей функцией, один для 2 значений R^и один для лучших подходят модели, что-то вроде:
df
# start_val fun_out R^2
# 1 {a=2,b=2} {22,24,26...} 0.8
# 2 {a=3,b=5} {35,38,41...} 0.6
Это код, который я до сих пор:
require(dplyr);require(tidyr)
foo <- function(x,a,b) a*x^2+b # function I am fitting
x <- 1:10 # independent variable
y_obs <- foo(x,1.5,2.5) + rnorm(length(x),0,10) # observed data (dependent variable)
start_range <- data.frame(a=c(1,2),b=c(2,3)) # range of allowed starting points for fitting
reps <- 2 # number of starting points to generate
# Create a data frame of starting points
df<-as.data.frame(sapply(start_range, function(x) runif(reps,min=x[[1]],max=x[[2]]))) %>%
mutate(id=seq_len(reps)) %>% # fudge to make nest behave as I want
nest(1:ncol(start_range)) %>%
mutate(data=as.list(data)) %>%
as.data.frame()
df
# id data
# 1 1 1.316356, 2.662923
# 2 2 1.059356, 2.723081
зависание теперь пытается передать параметры в данных в функции foo()
. Я попытался с помощью do.call()
, и даже при использовании постоянных параметров следующее сообщение об ошибке появляется:
mutate(df,y=do.call(foo,list(x,1,2)))
# Error: wrong result size (5), expected 2 or 1
Есть ли способ, чтобы создать столбцы dataframe, которые содержат списки непосредственно без использования nest()
?
Также при попытке создать список для перехода к do.call()
с использованием столбцов dataframe, как вы создаете список, в котором первым элементом является вектор x, второй параметр a, а третий - параметр b? Последовательность разделяет список по колонке:
mutate(df,my_list=list(x,data))
# id data my_list
# 1 1 1.316356, 2.662923 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
# 2 2 1.059356, 2.723081 1.316356, 2.662923, 1.059356, 2.723081
Вам нужно уловить ошибки из 'nls.lm' в вашей функции. Я предлагаю адаптировать исходный код 'nls2' (который, конечно же, не использует dplyr). – Roland
Спасибо @ Роланд, этот подход работал. – lapsel