2016-03-04 64 views
5

當我嘗試將參數傳遞到stat_summary中的round函數時(即使類似的代碼使用,說,geom_text)。這裏有一個例子:ggplot2:stat_summary在嘗試傳遞函數參數作爲參數時拋出錯誤,而不是硬編碼

# Fake data 
set.seed(5) 
dat = data.frame(group=rep(c("A","B"),each=10), val=rnorm(20)) 

我們將嘗試使用參數,設定位小數值標籤的數量,而不是硬編碼:

places = 2 

ggplot(dat, aes(group, val)) + 
    stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))) 

錯誤的eval(表達式,envir,enclos):找不到對象「地方」

但是,以下兩個示例可以正常工作。

ggplot(dat, aes(group, val)) + 
    stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., 2))) 

ggplot(dat, aes(group, val)) + 
    geom_text(aes(label=round(val, places))) 

我試圖寫一個ggplot函數時遇到了這個問題。起初我認爲這個問題涉及ggplot沒有從函數環境中獲取參數,但上面的例子表明這不是問題。爲了完整起見,下面是該函數的簡單示例以及錯誤消息。如果我將數字參數硬編碼爲round,而不是嘗試通過places參數,則該函數可以正常工作。

pp1 = function(data, group, var, places=2, e=1.5) { 

    ggplot(data, aes_string(group, var)) + 
    geom_boxplot() + 
    stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))) + 
    scale_y_continuous(limits = e * range(data[,var])) 

} 

pp1(dat, "group","val") 

錯誤的eval(表達式,ENVIR,enclos):對象「地方」未找到

,我希望能找到我是否做錯了什麼以及我如何獲得理想的行爲。

我正在運行R 3.2.3和ggplot2 2.1.0在OS X 10.10.5上。

+1

它看起來像一個NSE問題。你可以通過調用'eval(代替(... ggplot code ...,list(places = places)))'來躲避它,儘管可能有更好的方法。 – alistaire

+1

工作。請添加它作爲答案。你知道爲什麼它發生在'stat_summary'內部而不是在其他地方? – eipi10

+0

我不確定;這是關於'aes'中的NSE如何工作的。也許它會被'..y..'打開?有一個名爲'aes_'的SE版本,但我不知道如何讓'..y..'參數在其中工作。我會在上面發佈一個答案,我會在第二個答案中找到其他答案。 – alistaire

回答

2

aes使用non-standard evaluation,因此會嘗試在您提供的data參數內評估places。但是,它的NSE會有所不同,具體取決於您傳遞的內容。

繞過NSE的典型方法是substitute,它代替了代碼中的值。然後,您可以使用eval運行代碼:

eval(substitute(ggplot(dat, aes(group, val)) + 
        stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))), 
       list(places = places))) 

預期其工作原理:

plot with labels

哈德利還提供了aes幾個SE版本:aes_aes_qaes_string,這可能讓你避免使用substitute,但我無法評估..y..。 (如果有人知道如何構建它,評論和我會更新。)

哈德利還創建了lazyeval package,這對管理NSE很有用。

相關問題