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 ls 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