我想爲類似於nls2
(nls2庫)的Levenberg-Marquardt非線性最小二乘函數nls.lm
(minpack.lm庫)創建一個包裝,以給出用於評估模型與觀測數據擬合程度的蠻力方法。R - 使用嵌套的數據幀運行不同參數集的函數
的想法是創建一個範圍開始值的組合和任意的:
- 通過這些給函數,則該函數輸出與觀測到的數據,爲每個創建一個R^2值開始值組合並運行nls.lm配合其中最好的一個。對所有組合
或
- 運行nls.lm並選擇最佳的契合返回。
我想這樣做沒有循環和here吸氣後想使用嵌套dataframes,與參數輸入列表中的一個列,一個用於值通過我的函數返回的,一個是R^2個值,以及一個用於最適合的車型,是這樣的:
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
有沒有一種方法來創建它直接包含列表,而無需使用nest()
一個數據幀的列?
此外,當試圖創建列表使用數據幀列傳遞到do.call()
,如何創建一個列表,其中第一個元素是矢量x,第二個是參數a,第三個是參數b? follwing將列表拆分爲列:
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