通过另一个函数将数据和列名传递给ggplot [英] Passing data and column names to ggplot via another function

查看:143
本文介绍了通过另一个函数将数据和列名传递给ggplot的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将直接跳至示例并评论后缀:

I'll skip right to an example and comment afterwords:

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有一个已知的错误,其中aes()只会在全局环境中查看,而不会在本地环境中查看.遵循以下建议:在R中的另一个函数中使用ggplot(),我尝试了另一条路线.

Now, I know that ggplot2 has a known bug where aes() will only look in the global environent and not in the local environment. Following advice from: Use of ggplot() within another function in R, I tried another route.

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()

I don't know what that last line means. If I call: ggplot(cont,aes(x=value,y=variable,color=group))+geom_point()

我得到了您期望的图表.在命令行上,aes()在ggplot()中寻找变量名,但是在函数调用中却没有这样做.所以我试图改变我的电话:

I get the graph you would expect. At the command line, aes() is looking for the variable names in ggplot(), but it is not doing this within the function call. So I tried to change my call:

plot_scat(cont,cont$value,cont$variable,cont$group)

这让我得到了想要的东西.因此,我添加了下一层复杂性:

This gets me what I want. So I add the next layer of complexity:

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)来解决此问题.我不知道如何从这里继续.

My thought on this is that ser is actually cont$group, which is fine for use in aes(), but when passed to facet_grid is now a one column data frame with no information about value and variables. According to the help page, facet_grid does not take a "data=" argument so I cant use facet_grid(data=data,.~ser) to get around this. I don't know how to proceed from here.

这是一个非常简单的示例,但是长远的目标是让我可以给办公室中非R识字的人提供一个功能,然后说给它您的数据框名称,列名称和所需的列分裂,它将为您绘制漂亮的图块".它也将变得非常复杂,具有非常定制的主题,与我遇到的问题无关.

This is an extremely simple example, but the long term goal is to have a function I can give to non-R-literate people in my office and say "give it your data frame name, column names and the column you want to split on and it will make pretty plots for you". It will also get a lot more complex, with a very customized theme, which is irrelevant to the problems I'm having.

推荐答案

如果您不想将变量(列名)作为字符串/引号传递,那么我尝试了一种方法(另请参见

If you do not want to pass your variables (column names) as strings/quoted, then one approach that I tried (see also here) was to make use of match.call() and eval. It works with faceting (as in your case) as well:

library(ggplot2)

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))


plot_scat <- function(data, x, y, ser) {
    arg <- match.call()
    ggplot(data, aes(x = eval(arg$x),
                     y = eval(arg$y),
                     color = factor(eval(arg$ser)))) +
        geom_point() +
        facet_grid(. ~ eval(arg$ser))
}

# Call your custom function without quoting the variables
plot_scat(data = cont, x = value, y = variable, ser = group)

要了解match.call()的作用,也许可以尝试运行此代码:

To get an idea what match.call() does, maybe try to run this:

plot_scat <- function(data, x, y, ser) {
  str(as.list(match.call()))
}
plot_scat(cont, value, variable, group)
#> List of 5
#>  $     : symbol plot_scat
#>  $ data: symbol cont
#>  $ x   : symbol value
#>  $ y   : symbol variable
#>  $ ser : symbol group

reprex软件包(v0.2.1)于2019年1月10日创建 sup>

Created on 2019-01-10 by the reprex package (v0.2.1)

或者,另一种解决方法,但是这次将带引号的列名传递给自定义绘图功能是使用get():

Or, another workaround, but this time with passing quoted column names to the custom plotting function is using get():

plot_scat <- function(data, x, y, ser) {
    ggplot(data, aes(x = get(x),
                     y = get(y),
                     color = factor(get(ser)))) +
      geom_point() +
      facet_grid(. ~ get(ser))
  }

plot_scat(data = cont, x = "value", y = "variable", ser = "group")

这篇关于通过另一个函数将数据和列名传递给ggplot的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆