2012-11-06 237 views
2

如何更改函數參數名稱。對於使用替代品的例子,我可以改變函數的參數值或函數名稱:更改函數參數名稱

substitute(quote(F(x= A)), list(A= quote(B), F= quote(G))) 
## result 
quote(G(x = B)) 

但這不起作用:

substitute(quote(F(x= A)), list(x= quote(y))) 
## result 
quote(F(x = A)) 

# EDIT(@Joran這裏是真實的例子,也許不那麼真實但非常接近,我在做什麼)

library("multcomp") 
data("mtcars") 

mtcars$gear <- factor(mtcars$gear) 
mtcars$cyl <- factor(mtcars$cyl) 
xv <- c("gear","cyl") 

for(v in xv){ 
fo <- as.formula(paste("mpg",v,sep="~")) 
fit <- lm(fo,data=mtcars) 
print(eval(substitute(summary(glht(fit,linfct= mcp(vn="Dunnett"))),list(vn=v)))) 
} 
+3

我不會做任何。你真的想做什麼?通常在R中,你可能會做'foo < - 'G'; bar < - 'x'; do.call(foo,bar)'選擇一個函數及其基於字符串對象的參數。 –

+3

你真的想要做什麼? – joran

+1

@ Carl&Joran說了什麼(「你真的想做什麼?!」)。我會通過'formals()'自己改變參數... –

回答

4

以你的類似實際問題的一些例子,爲什麼不能做到這一點:

library("multcomp") 
data("mtcars") 

mtcars$gear <- factor(mtcars$gear) 
mtcars$cyl <- factor(mtcars$cyl) 
xv <- c("gear","cyl") 

ll <- list("Dunnett") 
for(v in xv){ 
    fo <- as.formula(paste("mpg",v,sep="~")) 
    fit <- lm(fo,data=mtcars) 
    names(ll) <- v 
    print(summary(glht(fit, linfct = do.call(mcp, ll)))) 
} 

其中給出:

 Simultaneous Tests for General Linear Hypotheses 

Multiple Comparisons of Means: Dunnett Contrasts 


Fit: lm(formula = fo, data = mtcars) 

Linear Hypotheses: 
      Estimate Std. Error t value Pr(>|t|)  
4 - 3 == 0 8.427  1.823 4.621 0.000144 *** 
5 - 3 == 0 5.273  2.431 2.169 0.072493 . 
--- 
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
(Adjusted p values reported -- single-step method) 


    Simultaneous Tests for General Linear Hypotheses 

Multiple Comparisons of Means: Dunnett Contrasts 


Fit: lm(formula = fo, data = mtcars) 

Linear Hypotheses: 
      Estimate Std. Error t value Pr(>|t|)  
6 - 4 == 0 -6.921  1.558 -4.441 0.000235 *** 
8 - 4 == 0 -11.564  1.299 -8.905 1.71e-09 *** 
--- 
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
(Adjusted p values reported -- single-step method) 

這裏的技巧是要注意的是,第一個參數mcp...這通常意味着我們可以通過表單list(tag = value)的列表。我們無法在此處指定tagv,因此只需使用單個元素"Dunnett"創建列表ll,然後將該列表中的名稱的屬性更改爲v即可。然後使用do.call()安排使用此參數列表調用mcp()

以及物品是否完整,從@Hadley列表@Josh metions上述評論,從這個answer可以使用setNames()功能更簡潔指出:

for(v in xv){ 
    fo <- as.formula(paste("mpg",v,sep="~")) 
    fit <- lm(fo,data=mtcars) 
    print(summary(glht(fit, linfct = do.call(mcp, setNames(list("Dunnett"), v))))) 
} 
+0

它可以縮寫爲:print(summary(glht(fit,linfct = setNames(eval mcp(vn =「Dunnett」)),v))))。 –

2

如果您必須動態地改變所提供的參數的名稱,你可以做這樣的事情:

cl <- quote(F(x = a)) 
names(cl)[names(cl) == "x"] <- "y" 
cl 
# F(y = a) 
3

按面值以你的問題的標題和第一線爲什麼不能複製的功能和/或取決於函數名稱還是參數需要更改,使用formals()

對於第一種:

F <- function(x = A) {} 
G <- F 
formals(G) <- alist(x = B) 

> args(G) 
function (x = B) 
NULL 

對於第二個

F <- function(x = A) {} 
formals(F) <- alist(y = A) 

> args(F) 
function (y = A) 
NULL 
1

看到的你真的做什麼的例子之後,你也可以使用parsesprintf

print(eval(parse(text=sprintf("summary(glht(fit,linfct= mcp(%s='Dunnett')))", 
    v)))) 
+1

我嘗試聽取Thomas Lumley在這方面的建議。 '需要( 「命運」);幸運(106)'。 –

+0

@GavinSimpson,但問題不是我的! (+1對你的答案) – BenBarnes

+1

/我檢查自己的代碼爲'parse' ... – BenBarnes

1

根據要求,評論轉移到答案:

我也不會這樣做。你真的想做什麼?通常在R中,您可以使用foo<- 'G'; bar<-'x' ; do.call(foo,bar)來選擇基於字符串對象的函數及其參數。

+0

+1用於提示do.call –