【问题标题】:change function argument name更改函数参数名称
【发布时间】:2012-11-06 14:29:36
【问题描述】:

如何更改函数参数名称。例如使用替代我可以更改函数参数值或函数名称:

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

# 编辑(@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))))
}

【问题讨论】:

  • 我也不会这样做。你真正想做的是什么?通常在 R 中,您可以使用 foo&lt;- 'G'; bar&lt;-'x' ; do.call(foo,bar) 来根据字符串对象选择函数及其参数。
  • 你真正想做什么?
  • @ Carl & Joran 所说的(“你真正想做的是什么?!”)。我自己会通过formals() 更改参数...
  • @Carl Witthoft 你能写下你的答案吗
  • 我认为您可能正在使用 multcomp。请参阅 Hadley 或我对 this question 的回答,这与您自己的基本相同。

标签: r


【解决方案1】:

以与实际问题类似的事情为例,为什么不这样做:

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) 形式的列表。我们不能在这里将tag 指定为v,因此只需使用单个元素"Dunnett" 创建列表ll,然后在循环中将此列表的names 属性更改为v。然后使用do.call() 安排调用mcp() 与此参数列表。

为了完整起见,正如@Josh 在上面的评论中提到的那样,来自@Hadley 的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)))))
}

【讨论】:

  • 可以简写为:print(summary(glht(fit, linfct= setNames(eval(mcp(vn= "Dunnett")),v))))。
【解决方案2】:

从表面上看你的问题标题和第一行为什么不复制函数和/或使用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

【讨论】:

    【解决方案3】:

    如果您必须动态更改所提供参数的名称,您可以执行以下操作:

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

    【讨论】:

      【解决方案4】:

      看到你真正在做的例子后,你也可以使用parsesprintf

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

      【讨论】:

      • 我在这方面尝试听取 Thomas Lumley 的建议。 require("fortunes"); fortune(106).
      • @GavinSimpson,但问题不是我的! (+1 对您的两个答案)
      【解决方案5】:

      根据要求,评论移至答案:

      我也不会。你真正想做的是什么?通常在 R 中,您可以使用 foo&lt;- 'G'; bar&lt;-'x' ; do.call(foo,bar) 来根据字符串对象选择函数及其参数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-23
        • 2015-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-18
        • 1970-01-01
        相关资源
        最近更新 更多