2012-04-14 58 views
5

我想將公式的右側傳遞給R函數,然後「公式」的左側添加並調用gam()。我想實現這個沒有醜as.formula()結構等如何將公式的右側傳遞給另一個公式?

我陷入了下面的最小的例子,你知道什麼地方出了問題嗎?

require(mgcv) 
set.seed(0) ## set.seed(1) 
gamEx1 <- gamSim(1, n=400, dist="normal", scale=2) ## simulate some data 
str(gamEx1) ## display structure 

## calling gam() and passing the right-hand side of a formula 
gamFitter <- function(formula.RHS, data, ...){ 
    z <- 2*data$y + data$f0 # some given values 
    gam(z ~ formula.RHS, data=data, ...) # call gam() 
} 

## call the function with the right-hand side of a formula 
gamFitter(formula.RHS=~s(x0)+s(x1)+s(x2)+s(x3), data=gamEx1) 

Error in model.frame.default(formula = z ~ formula.RHS, data = data, 
          drop.unused.levels = TRUE) : 
    invalid type (language) for variable 'formula.RHS' 

回答

12

似乎您應該使用R,na的內置功能的mely update.formula,沒有必要寫一個新的功能:

> form <- ~s(x0)+s(x1)+s(x2)+s(x3) 
> form 
~s(x0)+s(x1)+s(x2)+s(x3) 
> update.formula(form, z ~ .) 
z ~ s(x0) + s(x1) + s(x2) + s(x3) 
+0

謝謝,德里克,我不知道這個函數存在。 – 2012-05-04 04:48:31

+0

@MariusHofert在我看來,這個答案比目前接受的更優雅。你能重新考慮接受嗎? – Andrie 2013-08-05 13:26:02

4

缺憾,但它的工作原理:

form1 <- as.formula("hi ~ lo + mid") 
form2 <- as.formula("blue ~ red + green") 
form2[[3]] <- form1[[3]] 
> form2 
blue ~ lo + mid 
+0

嗯,因爲我寫的,我*不*希望使用'as.formula()'和字符串,這只是不好的做法。不管怎麼說,還是要謝謝你。 – 2012-04-14 15:39:22

+0

@MariusHofert - 你能解釋一下關於'as.formula()'的壞習慣嗎? – Chase 2012-04-14 16:45:25

+0

公式是一個公式 - 應該這樣對待。將它轉換爲/通過字符串處理它是不好的做法。請注意,建議使用公式構建函數的方法在此處處理:http://developer.r-project.org/model-fitting-functions.txt兩個很好的例子,它們不*涉及字符串(因此不需要'as.formula()')是'lm()'和'(mgcv::) gam'的函數。 – 2012-04-14 16:52:59

5

這裏是在@ GSK3的想法版本建設:

changeLHS <- function(formula, lhs) { 
    if (length(formula) == 2) { 
    formula[[3]] <- formula[[2]] 
    } 
    formula[[2]] <- substitute(lhs) 
    formula 
} 

changeLHS(a~b+c, z+w) # z + w ~ b + c 
changeLHS(~b+c, z+w) # z + w ~ b + c 

所以,你的代碼就變成了:

gamFitter <- function(formula.RHS, data, ...){ 
    frm <- changeLHS(formula.RHS, 2*y + f0) 
    gam(frm, data=data, ...) # call gam() 
} 
+0

*不錯*,謝謝。我想'rhs'應該在'changeLHS'中用'lhs'來表示更清楚,但是它確實很好。 – 2012-04-14 21:42:51

+0

@MariusHofert - 好點,我改變了。現在「右側」是左邊的,對吧? ;-) – Tommy 2012-04-14 21:46:17

0

建立在其他的答案,如果你需要更換LHS programmatically by passing strings(點菜reformulate),然後兩個小調整可以提供幫助。

使用@湯的做法:

changeLHS <- function(formula, lhs) { 
    if (length(formula) == 2) { 
     formula[[3]] <- formula[[2]] 
    } 
    formula[[2]] <- as.symbol(lhs) 
    formula 
} 

form <- ~s(x0)+s(x1)+s(x2)+s(x3) 
changeLHS(form, "z") 
## z ~ s(x0) + s(x1) + s(x2) + s(x3) 

使用@德里克的做法:

update(form, reformulate(".", "z")) 
## z ~ s(x0) + s(x1) + s(x2) + s(x3) 
相關問題