将参数传递给ggplot

时间:2011-06-27 04:59:37

标签: r ggplot2

想创建一个使用ggplot生成图形的函数。为简单起见,典型的图表可能是

ggplot(car, aes(x=speed, y=dist)) + geom_point() 

我想创建的函数是

类型
f <- function(DS, x, y) ggplot(DS, aes(x=x, y=y)) + geom_point()

然而这不起作用,因为x和y不是字符串。在以前的SO问题中已经注意到这个问题(例如,this one),但在我看来,没有提供令人满意的答案。如何修改上面的函数使其适用于任意数据框?

4 个答案:

答案 0 :(得分:38)

一种解决方案是将x和y作为数据帧DS中列的字符串名称传递。

f <- function(DS, x, y) {    
  ggplot(DS, aes_string(x = x, y = y)) + geom_point()  
}

然后将函数调用为:

f(cars, "speed", "dist")

然而,似乎你不想要那个?您能举例说明为什么需要不同的功能吗?是因为您不希望在同一数据框中包含参数吗?

答案 1 :(得分:7)

我认为以下类型的代码可能只构建aes组件。

require(ggplot2)

DS <- data.frame(speed=rnorm(10), dist=rnorm(10))

f <- function(DS, x, y, geom, opts=NULL) {
  aes <- eval(substitute(aes(x, y),
    list(x = substitute(x), y = substitute(y))))
  p <- ggplot(DS, aes) + geom + opts
}

p <- f(DS, speed, dist, geom_point())
p

然而,这似乎是一种复杂的方法。

答案 2 :(得分:1)

我能想到的一种方法是使用match.call()到达传递给自定义绘图函数的参数/参数所包含的变量名,然后在其上使用eval()。这样,如果您不喜欢,可以避免将它们作为引号传递给自定义函数。

library(ggplot2)

fun <- function(df, x, y) {
    arg <- match.call()
    ggplot(df, aes(x = eval(arg$x), y = eval(arg$y))) + geom_point()
} 
fun(mpg, cty, hwy) # no need to pass the variables (column names) as quoted / as strings

enter image description here

答案 3 :(得分:0)

另一种选择是使用do.call。以下是来自工作代码的单行复制粘贴:

gg <- gg + geom_rect( do.call(aes, args=list(xmin=xValues-0.5, xmax=xValues+0.5, ymin=yValues, ymax=rep(Inf, length(yValues))) ), alpha=0.2, fill=colors )