1

这是一个例子:

library(ggplot2)
library(scales) # for percent() function

custom_percent <- function(n){
    function(x){
         return(paste(percent(x), sprintf('(%d)', round(x* (n)))))
    }
 }

mydata = data.frame(x = rep(c('a','b','c'), each=100))

ggplot(mydata) + geom_text(aes_(x=~x, y=~..prop.., 
                           label=bquote(.(custom_percent)(length(x))(..prop..)),
                           stat='count')

该函数在这样的环境之外可以正常工作,但是为了将它与 一起使用ggplot,它必须以一种或另一种方式引用。

不幸的是,我无法弄清楚如何正确返回包含以这种方式传递的变量的生成函数。我试过这个:

custom_percent <- function(n){
    n = enquo(n)
    function(x){
         return(paste(percent(x), sprintf('(%d)', round(x* (!!n)))))
    }
 }

但是当我这样做时出现错误:Error in !n : invalid argument type

有谁知道如何正确使用n返回的函数中的期望值custom_percent()

在有人问之前,我知道我可以事先在摘要数据框中生成统计数据用作utils::getAnywhere()解决方法,但这不是问题的重点。

4

2 回答 2

1

问题不在于您的功能 - 最初编写时看起来不错。您的 geom_text 调用中缺少括号,我认为这是主要问题。

custom_percent <- function(n){
  function(x){
    return(paste(percent(x), sprintf('(%d)', round(x* (n)))))
  }
}

# I made the data slightly more variable
mydata = data.frame(x = rep(c('a','b','c'), rbinom(3, 100, .8)))

ggplot(mydata, aes(x = x)) + 
  # geom_bar(stat = 'count') + 
  geom_text(aes_(label=bquote(.(custom_percent)(length(x))(..count.. / sum(..count..)))),
    stat='count')

我认为这可以让你得到你想要的(并且..prop..在那里投入也可以,这个数据只是平坦的 1s - 这对我来说没有意义。如果那是你想要/期望的,一定要把它切换回来。你可以检查出https://sebastiansauer.github.io/percentage_plot_ggplot2_V2/ - 这显示了你可以在哪里使用..prop..and ..count..,但它并没有真正解释为什么)。

您可以做的另一件事(利用..prop..所写的):

ggplot(mydata, aes(x = x, y = ..prop..), stat = 'count') + 
  # geom_bar(aes(y = ..prop..), stat = 'count') +
  geom_text(aes_(label=bquote(.(custom_percent)(length(x))((..count..) / sum(..count..)))),
    stat='count') + 
  scale_y_continuous(labels=scales::percent)
于 2018-04-09T02:58:04.690 回答
0

您可以使用基数 rsubstitute来捕获整个表达式,然后将表达式写为functionBody

custom_percent <- function(n){
 n=eval(n)
 m=substitute(return(paste(percent(x), sprintf('(%d)', round(x*n)))))
 `functionBody<-`(function(x)1,parent.frame(),m)
}

s=3
custom_percent(s)
function (x) 
return(paste(percent(x), sprintf("(%d)", round(x * 3))))

如您所见,n已替换为3. 您可以尝试任何其他号码。它会起作用

于 2018-04-08T23:28:20.483 回答