2013-07-16 38 views
11

我正在嘗試編寫一個R函數,它接收一個數據集並輸出plot()函數,其中讀取的數據集環境。這意味着你不必再使用attach(),這是很好的做法。這是我的例子:在R中,出現以下錯誤:「嘗試複製'closure'類型的對象」

mydata <- data.frame(a = rnorm(100), b = rnorm(100,0,.2)) 
plot(mydata$a, mydata$b) # works just fine 

scatter_plot <- function(ds) { # function I'm trying to create 
    ifelse(exists(deparse(quote(ds))), 
     function(x,y) plot(ds$x, ds$y), 
      sprintf("The dataset %s does not exist.", ds)) 
    } 

scatter_plot(mydata)(a, b) # not working 

這裏是我得到的錯誤:

Error in rep(yes, length.out = length(ans)) : 
    attempt to replicate an object of type 'closure' 

我嘗試了其他幾個版本,但他們都給予我同樣的錯誤。我究竟做錯了什麼?

編輯:我意識到代碼不太實際。我的目標是更好地理解函數式編程。我在SAS寫了一個類似的宏,我只是試圖寫在R中的對應部分,但我失敗了。我只是以此爲例。我認爲這是一個非常簡單的例子,但它不起作用。

+0

你的代碼試圖做的是過於標新立異。你能說你想要達到什麼嗎? – asb

回答

13

有幾個小問題。 ifelse是矢量化函數,但您只需要一個簡單的if。事實上,你並不需要else - 如果數據集不存在,你可以立即拋出一個錯誤。請注意,您的錯誤消息不使用對象的名稱,所以它會創建它自己的錯誤。

您正在通過ab而不是"a""b"。在編程時(fortunes::fortune(312)),應該使用ds[[x]]語法而不是ds$x語法。如果這是你想要調用函數的方式,那麼你也必須去掉這些參數。最後,我想你想deparse(substitute())而不是deparse(quote())

scatter_plot <- function(ds) { 
    ds.name <- deparse(substitute(ds)) 
    if (!exists(ds.name)) 
    stop(sprintf("The dataset %s does not exist.", ds.name)) 
    function(x, y) { 
    x <- deparse(substitute(x)) 
    y <- deparse(substitute(y)) 
    plot(ds[[x]], ds[[y]]) 
    } 
} 
scatter_plot(mydata)(a, b) 
+2

當我應該使用'if'時,我在使用'ifelse'後結束了這個事情。 –

相關問題