2013-10-06 68 views
3

我想結合產生高斯ň功能,並使用從nls運行檢索值的評估時間。我用gsub用反向引用替換原始係數與nls。但是,數據框上的[似乎在\\1之前評估。反向引用在GSUB

這裏是一個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") 

正如你所看到的,替換是來港定居,而調用NLS數據幀似乎是有效的:

gsub("(a|b|c)",paste0(" ","\\1","Estimate"," "),"a + b*x + c*x^2") 

任何想法耽誤評估[

謝謝!編輯:爲了清楚起見,這裏是全功能,現在工作很好(它需要峯的數量,一個峯值的公式,公式中的參數,變量,常量布爾值和nls結果作爲參數,並返回在ggplotstat_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 
} 

這裏是一個使用實例(不包括對長緣故NLS數據):

> 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))" 

謝謝你的幫助

回答

5

1)gsub用一個常量替換一個模式,但是你要做的是用對匹配的字符串應用函數的結果替換它。 gusbfngsubfn package這樣做。下面,第二個參數中的公式只是gsubfn的一個函數的簡短形式,其參數是左側,正文是右側。交替的第二個參數可在通常的功能表示法(function(x) nls[x,]),但在比特冗長爲代價來表示:

> library(gsubfn) 
> gsubfn("a|b|c", x ~ nls[x, ], "a + b*x + c*x^2") 
[1] "1 + 2*x + 3*x^2" 

注意"a|b|c"可以從nls爲了避免多餘的說明書使用paste(rownames(nls), collapse = "|")導出。

2)雖然gsubfn簡化了這一顯著,要做到這一點,而不使用gsubfnsubstitute

> 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 is the text as a "call" object 
> s <- do.call(substitute, list(e, L))    # perform the substitution 
> format(s)          # convert to character 
[1] "1L + 2L * x + 3L * x^2" 

L s到,由於在這個問題定義nls包含整數的事實是由於。將它們轉換爲數字運行上面之前,如果你不喜歡:

nls[[1]] <- as.numeric(nls[[1]]) 

3)另一種可能性是遍歷字符串被取代。

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

如果我們知道沒有每個出現了多次被替換,我們可以代替gsub使用sub這裏。

更新:更正了第二個解決方案。

更新2:增加了第三個解決方案。

+0

非常感謝你,因爲我原來的問題是更復雜一點,雖然我不能用第二個提案。我會在完整問題(明天)進行更廣泛的測試後接受你的回答。再次感謝 ! –

+0

我已經更新了代碼來計算'L'以顯示它如何從'nls'派生。 –

+0

並進一步更新,以顯示如果二次方程表示爲字符串如何執行此操作。 –

1

這裏是另一種方式來做到這一點

gsub(paste0(row.names(nls), "(.*)", collapse=""), paste0(t(nls), paste0("\\", 1:nrow(nls)), collapse=""), "a + b*x + c*x^2" ) 
[1] "1 + 2*x + 3*x^2" 
+0

即使當我添加缺少的右括號,這不起作用... – Frank

+0

@Frank謝謝指出。修正了括號錯誤。 –

+0

感謝您的意見,但'gsubfn'解決方案更適合我的特定問題。 –