【问题标题】:R : pass Graph as parameter to a functionR:将 Graph 作为参数传递给函数
【发布时间】:2015-09-04 06:20:29
【问题描述】:

我有一个看起来不错的图表,我用它来绘制

r <- ggplot(data=data2.Gurgaon,aes(x=createdDate,y=count))+geom_point()

现在我想在图表上突出显示几个点,比如 500,1000,5000 等。 所以,我正在尝试编写一个函数,在其中我可以通过我想要标记的点 下面是我写的函数

graphPoint <- function(graph,point) {
  g <- graph
  g <- g+geom_point(aes(x=createdDate[point],y=count[point]),pch=1,size=8,col='black')
  g <- g+ geom_point(aes(x=createdDate[point],y=count[point]),pch=16,size=5,col='red')
  g
}

当我传递参数时

r -> graphPoint(r,500)

这是报错

Error in lapply(X = x, FUN = "[", ..., drop = drop) : 
  object 'point' not found

我对 R 不是很好。希望它可能,但我在一些小点上失踪了......谢谢。

【问题讨论】:

  • 您是否有理由要在函数中执行此操作?否则,您可以在原始数据中添加一个“突出显示”变量,并以此为您的点着色/更改大小。

标签: r rstudio


【解决方案1】:

这实际上是ggplot 中的一个极其微妙(且令人讨厌...)的问题,尽管不是错误。 aes(...) 函数首先在默认数据集的上下文中评估所有符号(例如,它查找具有该名称的列),如果在全局环境中失败。它不会像您有理由期望的那样向上移动调用链。因此,在您的情况下,符号point 首先在data2.Gurgaon 的上下文中进行评估。由于没有这样的列,它会在全局环境中查找point,但在您的graphPoint(...) 函数的上下文中。这是一个演示:

df <- mtcars
library(ggplot2)
graphPoint <- function(graph,point) {
  g <- graph
  g <- g + geom_point(aes(x=wt[point],y=mpg[point]),pch=1,size=8,col='black')
  g <- g + geom_point(aes(x=wt[point],y=mpg[point]),pch=16,size=5,col='red')
  g
}

ggp <- ggplot(df, aes(x=wt, y=mpg)) + geom_point()
point=10
graphPoint(ggp, 10)

之所以这样,是因为我在全局环境中定义了point;函数内的 point 变量被忽略(您可以通过使用 10 以外的其他值调用 fn 来证明这一点:您将得到相同的图)。

解决此问题的正确方法是对data=... 参数进行子集化,如另一个答案所示。

【讨论】:

    【解决方案2】:

    您不能像您尝试做的那样在 ggplot 函数的美学部分中选择数据的子集。但是,您可以通过从 ggplot 对象中提取原始数据、对其进行子集化并在函数的其余部分中使用子集来实现此目的。

    r <- ggplot(data=mtcars,aes(x=cyl,y=drat))+geom_point()
    
     graphPoint <- function(graph,point) {
      g <- graph
      data_subset <- g$data[point, ]
      g <- g+geom_point(data = data_subset, 
                        aes(x=cyl,y=drat),pch=1,size=8,col='black')
      g <- g+ geom_point(data = data_subset,
                         aes(x=cyl,y=drat),pch=16,size=5,col='red')
      g
     }
    
     graphPoint(r, point = 2)
    

    PS 对于即将发布的帖子,我建议您使用通常可访问的数据(例如 mtcars 数据)来制作一个可重复的示例。这样可以更轻松地帮助您。

    【讨论】:

    • 您的代码确实可以运行,但严格来说,“您不能在 ggplot 函数的美学部分中选择数据的子集......”并不完全正确。事实上你可以。 OP 的代码失败的原因是因为他在 函数内aes(...) 调用中使用了 point