Как использовать строку в качестве входных аргументов для функции R и использовать метод нелинейного фитинга nls? - PullRequest
0 голосов
/ 22 января 2020

Я пишу сценарий, в котором я хотел бы подогнать нелинейную функцию (лоренцеву) к некоторым данным. В конечном счете, я хочу, чтобы входные аргументы были удалены из функции и вместо этого предоставлены списком. Это сделано для того, чтобы я мог создавать растущий список аргументов без изменения функции. Я могу сделать это без особых проблем, однако затем я не могу использовать алгоритм подбора nls для точного подбора данных и определения коэффициентов.

Стандартный подход

Все входные аргументы работают в функции, работает нормально:

stepsize<-25/500 #Define step size
x=seq(-10, 10, by=stepsize) # Define x-axis

a0=0.5 #width
b0=2 #x-position of peak
y <- (1/pi)*(a0*0.5/((x+b0)^2+(a0/2)^2))+rnorm(401,0,0.1) # Create y-axis based on Lorentzian function with random noise

plot(x,y) # Plot data to check

fit<-function(x,a0,b0){ #Define function which will be used to "Fit" the dummy data.
  f<-(1/pi)*(a0*0.5/((x+b0)^2+(a0/2)^2))
}

a<-c(0.4)#Define some approximations for the fit
b<-c(2.3)

m<-nls(y ~ fit(x,a0,b0), start = list(a0=a, b0=b), #run the fitting model
       control=nls.control(maxiter=50, tol=1e-5, minFactor = 1/2048, warnOnly=TRUE),
       trace=TRUE)

plot(x,y)# Plot raw data
lines(x,predict(m),lty=1,col="red",lwd=1) #Add fitted line

Альтернативный (не работает) подход

Однако, ниже приведен код, который не работает, в котором я пытаюсь указать список входных аргументов вне основной функции:

rm(list = ls()) #clear history

stepsize<-25/500 #Define step size
x=seq(-10, 10, by=stepsize) # Define x-axis

a0=0.5 #width
b0=2 #x-position of peak
y <- (1/pi)*(a0*0.5/((x+b0)^2+(a0/2)^2))+rnorm(401,0,0.1) # Create y-axis based on Lorentzian function with random noise

plot(x,y) # Plot data to check

pfit<-function(parameters){#Define function which will be used to "Fit" the dummy data.

  v=unlist(parameters)
  a00=v[1+401] #The 401 is added because there are 400 values of x in the list before the fitting coefficients
  b00=v[2+401]

  f<-(1/pi)*(a00*0.5/((x+b00)^2+(a00/2)^2))
}


a<-c(0.4)#Define some approximations for the fit
b<-c(2.3)

plist=list(x,a,b)#Create list of input arguments

g<-pfit(plist)#test it works with initial guesses
plot(x,y)
lines(x,g,lty=1,col="red",lwd=1)

p=list(a00=a, b00=b) #create a list of starting parameters (i.e. the guess)

m<-nls(y ~ pfit(p), start = p, #run the fitting model
       control=nls.control(maxiter=50, tol=1e-5, minFactor = 1/2048, warnOnly=TRUE),
       trace=TRUE)

plot(x,y) # Plot raw data
lines(x,predict(m),lty=1,col="red",lwd=1) #Add fitted line

Проблема, скорее всего, заключается в догадках 'start' в скрипте nls, но после недели попыток различных перестановок у меня закончились идеи. Любая поддержка будет высоко ценится

...