想创建一个使用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),但在我看来,没有提供令人满意的答案。如何修改上面的函数使其适用于任意数据框?
答案 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
答案 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 )