I am trying to generate functions combining n gaussians, and using values retrieved from a nls
run. I use gsub
to replace the original coefficients with the nls
ones using backreferences. However, it seems that [
on the datafame evaluates before the \\1
.
Here is a MWE :
nls <- data.frame(Estimate = seq(1,3))
row.names(nls) <- c("a","b","c")
gsub("(a|b|c)",paste0(" ",nls["\\1","Estimate"]," "),"a + b*x + c*x^2")
As you can see, the replacements are NAs, while the call to the nls dataframe appear to be valid :
gsub("(a|b|c)",paste0(" ","\\1","Estimate"," "),"a + b*x + c*x^2")
Any ideas to delay the evaluation of [
?
Thanks !
EDIT : for the sake of clarity, here is the full function now working great (it takes number of peaks, formula of one peak, parameters in the formula, variable, constant boolean, and nls results as arguments, and returns the formula for use in ggplot
's stat_function()
:
Generate_func <- function(peakNb,peakForm,peakParams, peakVar, constBool,nls){
res <- as.data.frame(summary(nls)$coefficients, optional = T)
rhs <- strsplit(peakForm, "~")[[1]][[2]]
regex <- paste0("([*+-/\\^\\(\\)[:space:]]|^)(",paste0(peakParams, collapse = "|"),")([*+-/\\^\\(\\)[:space:]]|$)")
exp_names <- paste0(sapply(seq(1,peakNb),function(i){
paste0(sapply(peakParams, function(j){
paste0(j,i)
}))
}))
if(constBool){exp_names <- c("C", exp_names)}
func_text <- paste0(sapply(seq(1,peakNb),function(n){gsubfn(regex, x + y + z ~ paste0(x,res[paste0(y,n),"Estimate"],z), rhs )}), collapse = " + ")
func_text <- paste0(ifelse(constBool,paste0(res["C","Estimate"]," + "),""), func_text)
func <- function(x){
eval(parse(text = func_text))
}
names(formals(func)) <- c(peakVar)
print(func_text)
func
}
And here is an usage example (nls data not included for length sake):
> testfunc <- Generate_func(3, "intensity_cnt ~ a * exp((-(energy_eV-b)^2)/(2*c^2))", c("a","b","c"), "energy_eV", constBool = T, testnls)
[1] "1000 + 32327.6598743022 * exp((-(energy_eV-1.44676439236578)^2)/(2*0.0349194350021539^2)) + 10000 * exp((-(energy_eV-1.49449385009962)^2)/(2*0.0102269096492807^2)) + 54941.8293572164 * exp((-(energy_eV-1.5321664735001)^2)/(2*0.01763494864617^2))"
Thank you for your help !