【问题标题】:ggplot is not working properly inside a function despite working outside it - R尽管在函数外工作,但ggplot在函数内无法正常工作-R
【发布时间】:2014-01-17 16:48:35
【问题描述】:

我正在尝试创建一个函数,该函数接受 2 个参数并为它们输出适当的 ggplot。该代码手动完美运行,但不知何故我无法使其在函数包装器中运行。

返回的错误是

Error in eval(expr, envir, enclos) : object 'TimeVector' not found

我尝试通过强制将未找到的 objects 作为字符串添加到 ggplot 来纠正这一点。 这反过来又会以

的形式产生不同的麻烦
Error: Discrete value supplied to continuous scale

删除 scale_x_continuous(breaks=0:24) 修复了第二个错误,但输出了一个空图,这表明 ggplot 根本没有提供任何数据。

数据是按时间分组的交通密度观察的大型数据框。它看起来像这样:

ID                   Road Status                Time Statusint Day  Months Year Weekday

1 Me7war To Sheikh Zayid Orange 2012-10-01 00:03:00         3   1 October   12  Monday
1 Me7war To Sheikh Zayid  Green 2012-10-01 05:00:00         2   1 October   12  Monday
1 Me7war To Sheikh Zayid Yellow 2012-10-01 05:24:00         5   1 October   12  Monday

我正在尝试根据“时间”变量绘制“Statusint”变量,它是从 1(良好流量)到 5(糟糕流量)的状态整数的缩写。 “时间”被格式化为 Posix,因此我创建了一个名为“TimeVector”的数字向量,其唯一目的是在 ggplot 中进行绘图。

函数如下:

Plotroad <- function( roadID , Day ) {

  *** Working Code ***

  else { 

  ### THE PROBLEM CODE: Everything below works manually, but returns an error in the function

    Roadsubset <- October[October$ID == as.numeric(roadID), ] 
    Timesubset <- subset(Roadsubset, format(Roadsubset$Time,'%d') == "Day" )
    TimeVector <- as.numeric(gsub(":" , "." , strftime(Timesubset$Time, format="%H:%M")))

    ggplot(Timesubset, aes( x = "TimeVector", y = "Timesubset$Statusint")) + geom_point() +  
        stat_smooth() + scale_x_continuous(breaks=0:24) 


    ### The working code: 
    Roadsubset <- October[October$ID == as.numeric(roadID), ] 
    Timesubset <- subset(Roadsubset, subset = Roadsubset$Day == as.integer(Date) )
    TimeVector <- as.numeric(gsub(":" , "." , strftime(Timesubset$Time, format="%H:%M")))
    Timesubset$timevector <- TimeVector

    print(ggplot( data = Timesubset, aes_string( x = "timevector" , y = "Statusint" )) + geom_point() + stat_smooth()  + scale_x_continuous(breaks=0:24) + labs(list(title = as.character(Timesubset$Road[1]) , x = "Time of Day", y = "Status")))  

  }
}

我看到一些 advice 建议使用 print,因为 ggplot 不是在命令行中调用的。但是,这并不能解决上述错误。

这是我关于堆栈溢出的第一篇文章,所以如果需要,请指出我如何更好地格式化未来的问题。谢谢。

【问题讨论】:

  • tl;dr,但您似乎在寻找aes_string
  • @Roland Danke, aber 这又会产生一个新错误:Error in parse(text = x)[[1]] : subscript out of bounds
  • 试着把这个aes( x = "TimeVector", y = "Timesubset$Statusint")) 改成aes_string( x = "TimeVector", y = "Statusint")) 我相信你不应该继续在aes() 调用中添加数据引用。 Here is a similar question
  • 尝试只使用一个包含所有数据的data.framelong format。检查此Question 以了解如何制作可重现的示例。
  • @MartínBel 做这两件事帮助很大,谢谢

标签: r function debugging ggplot2


【解决方案1】:

除了使用变量名之外,还有一个作用域问题。 GGPlot 在全局环境中执行非标准评估,因此您的函数中定义的任何内容都不能直接访问,除了“数据”参数,因为该参数是显式传递的,而不是通过非标准评估。因此,解决此问题的一种方法是将变量添加到 data 参数中。我创建了一个我认为模仿您的问题的示例,但由于我没有您的数据,所以它并不相同:

gg_fun <- function() {
  data <- data.frame(a=1:10, b=1:10)
  clr <- rep(c("a", "b"), 5)
  ggplot(data, aes(x=a, y=b, color=clr)) + geom_point()
}
gg_fun()
# Error in eval(expr, envir, enclos) : object 'clr' not found
gg_fun <- function() {
  data <- data.frame(a=1:10, b=1:10)
  clr <- rep(c("a", "b"), 5)
  data$clr <- clr
  ggplot(data, aes(x=a, y=b, color=clr)) + geom_point()
}
gg_fun() # works

在您的情况下,您需要将TimeVector 添加到Timesubset(简单),然后使用不带引号的aes 语法:

ggplot(Timesubset, aes(x=TimeVector, y=Statusint)) ...

【讨论】:

  • 是的,似乎就是这样。谢谢
  • 我有一个类似的问题,ggplot 找不到我的颜色向量,但我的颜色向量有四个值匹配我的 data.frame 中的四个因子,它有 1200 个观察值。我的 data.frame 不允许我将四项向量添加为列。对这种情况有任何编辑吗?或者这是一个单独的问题?
  • @mightypile,只需制作一个与您的数据框长度相同的向量,并使用您想要的每行颜色。 match 可能会帮助完成这项任务。
  • @BrodieG,这样做会产生“错误:集合美学的长度不兼容:颜色、大小、hjust、vjust、x、y、标签”。我用十几种不同的方式弄乱了颜色和标签。我想我只需要重构和清理东西。一个更优雅的解决方案等待我的努力。谢谢!
  • @BrodieG 我认为使用“与您的数据框长度相同”这一短语可能会产生误导。您几乎总是希望创建一个长度与数据帧的行数相同的向量。
猜你喜欢
  • 1970-01-01
  • 2016-01-06
  • 2022-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 2012-03-31
  • 1970-01-01
相关资源
最近更新 更多