我会跳过一个例子并评论后面的话:
cont <- data.frame(value = c(1:20),variable = c(1:20,(1:20)^1.5,(1:20)^2),group=rep(c(1,2,3),each=20))
value variable group
1 1 1.000000 1
2 2 2.000000 1
3 3 3.000000 1
#... etc.
#ser is shorthand for "series".
plot_scat <- function(data,x,y,ser) {
ggplot(data,aes(x=x,y=y,color=factor(ser)))+geom_point()
}
plot_scat(cont,value,variable,group)
#This gives the error:
#Error in eval(expr,envir,enclose) : object 'x' not found
现在,我知道ggplot2有一个已知的bug,其中aes()只会查看全局环境而不是本地环境 . 根据以下建议:Use of ggplot() within another function in R,我尝试了另一条路线 .
plot_scat <- function(data,x,y,ser) {
#environment=environment() added
ggplot(data,aes(x=x,y=y,color=factor(ser)),environment=environment())+geom_point()
}
plot_scat(cont,value,variable,group)
#This gives the error:
#Error in eval(expr,envir,enclos) : object 'value' not found
#In addition: Warning message:
#In eval(expr,envir,enclos) : restarting interrupted promise evaluation
我不知道最后一行意味着什么 . 如果我调用:ggplot(cont,aes(x = value,y = variable,color = group))geom_point()
我得到了你期望的图表 . 在命令行中,aes()正在ggplot()中查找变量名,但是它没有在函数调用中执行此操作 . 所以我试着改变我的电话:
plot_scat(cont,cont$value,cont$variable,cont$group)
这让我得到了我想要的东西 . 所以我添加了下一层复杂性:
plot_scat <- function(data,x,y,ser) {
#added facet_grid
ggplot(data,aes(x=x,y=y,color=factor(ser)),environment=environment())+geom_point()+
facet_grid(.~ser)
}
plot_scat(cont,cont$value,cont$variable,cont$group)
#This gives the error:
#Error in layout_base(data, cols, drop = drop):
# At least one layer must contain all variables used for facetting
我的想法是,ser实际上是cont $ group,在aes()中使用很好,但是当传递给facet_grid时,现在是一个单列数据框,没有关于值和变量的信息 . 根据帮助页面,facet_grid没有采用“data =”参数,所以我不能使用facet_grid(data = data, . 〜ser)来解决这个问题 . 我不知道怎么从这里开始 .
这是一个非常简单的例子,但长期目标是我可以为我办公室里的非R文化人员提供一个功能,并说“给它你的数据框名称,列名和要拆分的列它会为你制作漂亮的情节“ . 它也将变得更加复杂,具有非常自定义的主题,这与我遇到的问题无关 .
2 回答
您可以使用aes_string()代替aes()并将列名称作为字符串传递 .
facet_grid
需要一个公式,因此您可以使用as.formula将字符串解析为公式 .如果你不想把你的变量(列名)作为字符串/引用传递,那么我尝试的一种方法(参见here)就是使用
match.call()
和eval
. 它也适用于分面(如你的情况):要了解
match.call()
的作用,也许可以尝试运行:由reprex包创建于2019-01-10(v0.2.1)
或者,另一种解决方法,但这次将引用的列名称传递给自定义绘图函数是使用
get()
: