r - Backreferences evaluation time in gsub -
i trying generate functions combining n gaussians, , using values retrieved nls
run. use gsub
replace original coefficients nls
ones using backreferences. however, seems [
on datafame evaluates before \\1
.
here 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 can see, replacements nas, while call nls dataframe appear valid :
gsub("(a|b|c)",paste0(" ","\\1","estimate"," "),"a + b*x + c*x^2")
any ideas delay evaluation of [
?
thanks !
edit : sake of clarity, here full function working great (it takes number of peaks, formula of 1 peak, parameters in formula, variable, constant boolean, , nls results arguments, , returns formula 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 usage example (nls data not included length sake):
> testfunc <- generate_func(3, "intensity_cnt ~ * 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 !
1) gsub
replaces pattern constant looking replace result of applying function matched string. gusbfn
in gsubfn package that. below, formula in second argument gsubfn's short form function argument left hand side , body right hand side. alternately second argument expressed in usual function notation ( function(x) nls[x,]
) @ expense of bit of verbosity:
> library(gsubfn) > gsubfn("a|b|c", x ~ nls[x, ], "a + b*x + c*x^2") [1] "1 + 2*x + 3*x^2"
note "a|b|c"
derived nls
using paste(rownames(nls), collapse = "|")
in order avoid redundant specification.
2) although gsubfn
simplifies significantly, without gsubfn
use substitute
:
> l <- as.list(setnames(nls[[1]], rownames(nls))) # l <- list(a = 1l, b = 2l, c = 3l) > e <- parse(text = "a + b * x + c * x ^ 2")[[1]] # e text "call" object > s <- do.call(substitute, list(e, l)) # perform substitution > format(s) # convert character [1] "1l + 2l * x + 3l * x^2"
the l
s due fact nls
defined in question contains integers. convert them numeric before running above if don't that:
nls[[1]] <- as.numeric(nls[[1]])
3) possibility loop on strings substituted.
> s <- "a + b*x + c*x^2" > for(nm in rownames(nls)) s <- gsub(nm, nls[nm, ], s) > s [1] "1 + 2*x + 3*x^2"
if knew there no more 1 occurrence of each replaced use sub
in place of gsub
here.
update: corrected second solution.
update 2: added third solution.
Comments
Post a Comment