2012-06-08 92 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