2012-06-08 91 views
2

我试图创建一个封闭函数这将(?):将参数传递给一个封闭

  • 过程中的一些数据,该数据的
  • cat()结果,
  • 请求用户输入(即经由readline())基于该cat()的结果,
  • 然后返回的函数,其中返回的函数的参数默认中的一个是由readline()输入的值。

此外,我想返回的函数的参数的其余默认值是用户可解释的。也就是说,我不希望默认值是隐藏在父环境中的变量的变量名(这个规定排除了简单的参数传递)。具体来说,我希望arg()可以返回实际评估的数字等。

我已经在下面制作了此解决方案,但感觉笨拙和尴尬。有没有更好的方法来处理这个问题?

top <- function(year=1990, n.times=NULL){ 

if(is.null(n.times)){ 
    ###in the real function, data would be processed here 
    ###results would be returned via cat and 
    ###the user is prompted return values that reflect a decision 
    ###made from the processed data 
    n.times <- as.numeric(readline("how many times?")) 
} 


out <- function(year, n.times){ 
    ###in the real function, this is where most of the work would happen 
    rep(year, n.times) 
} 

###this entire section below is clunky. 
if(!identical(names(formals()), names(formals(out)))){ 
    stop("internal error: mismatching formals") 

} 

pass.formals <- setdiff(names(formals()), "n.times") 

formals(out)[pass.formals] <- formals()[pass.formals] 
formals(out)$n.times <- n.times 
out 

} 

x <- top() 
x 
+0

我没有答案,但强烈建议你为你的功能选择一个不同的名称。 'outer'是base-R中的矩阵创建函数。处理参数的常用方法是使用'match.arg()'函数。 –

+0

我不会在这个玩具的例子中伤害任何东西,但我仍然修复它。 – Michael

回答

2

对我来说这看起来一般都没问题;只有几件事我会做不同的事情。

是否有任何理由认为top()out()的参数似乎对应某些 的方式?即,您是否需要identical支票?不知道,所以我把它拿出来了。这似乎是你 想要什么,并且稍短:

top <- function(year=1990, n.times=NULL){ 
    if (is.null(n.times)) { 
     n.times <- as.numeric(readline("how many times?")) 
    } 

    out <- function(year, n.times) { 
     rep(year, n.times) 
    } 

    out.formals = formals(out) 
    out.formals['n.times'] = n.times 
    formals(out) = out.formals 

    out 
} 

编辑:如果你想使用超[R魔法,你可以写

top <- function(year=1990, n.times=NULL){ 
    if (is.null(n.times)) { 
     n.times <- as.numeric(readline("how many times?")) 
    } 

    `formals<-`(
     function() { 
      rep(year, n.times) 
     }, 
     value=list(year=alist(x=)$x, n.times=n.times) 
    ) 
} 

编辑:您也可以使用像迪文建议的东西(虽然我不能 得到它与substitute):

out = function(year, n.times) { 
     rep(year, n.times) 
    } 
    `formals<-`(out, v=`[[<-`(formals(out), 'n.times', n.times)) 

或者使用bquote

eval(bquote(
     function(year, n.times=.(n.times)) { 
      rep(year, n.times) 
     } 
    )[-4L]) 

你有这么多的选择。

+0

你可以做一些更紧凑的东西,比如''formals <-'(out,substitute(formals(out),list(ntimes = n.times))''?对不起,我无法在评论中正确显示反引号。 –

+0

@DWin我希望,但我不能让它与'substitute'一起工作。但是同样的想法可以用于[[<-'。 – Owen