R:在ggplot2中循环错误

时间:2014-04-02 13:03:11

标签: r ggplot2

我正在尝试使用循环来简化ggplot命令,但它只将循环的最后一部分分配给我的ggplot对象。

plot.test = ggplot(data = plot.df, aes(x = xvariable)) + 
  geom_line(aes(y = yvariable)) 

for (i in 1:6){
  plot.test = plot.test + geom_point(aes(y = ypoints[i], x = xpoints[i])) 
}

所以,问题是,在运行循环之后,plot.test只包含原始行和循环中的最后一个点,即点(x[6],y[6]

关于如何解决这个问题的任何想法?

3 个答案:

答案 0 :(得分:3)

你为什么要这样做?

ggplot( data = plot.df, aes( x = xvariable, y = yvariable ) ) +
  geom_line() +
  geom_point( data = plot.df[1:6,], aes( y = ypoints, x = xpoints ) )

你在找什么?

修改

在我的原始答案中,我写了您无法将多个相同类型的几何对象添加到一个ggplot 。这显然是错误的,如下例所示:

dt <- data.frame( x = rnorm(1:10), y = rnorm(1:10) )
ggplot( mapping = aes( x = x, y = y ) ) +
  geom_point( data = dt[1:5,] ) +
  geom_point( data = dt[6:10,] )

但是,我很难想到一个必要的例子。根据我的经验,我总是假设在同一个图中使用两次相同geom的原因是由于数据模型不正确。

答案 1 :(得分:1)

这是一个可以使用的数据集。

plot.df <- data.frame(xvariable=1:6, yvariable=1:6+rnorm(6,0,0.3), xpoints=1:6+rnorm(6,0,0.1), ypoints=1:6+rnorm(6,0,0.1))

可以将多个相同类型的几何对象添加到一个ggplot中。例如:

ggplot(data = plot.df, aes(x = xvariable)) + 
  geom_line(aes(y = yvariable)) +
  geom_point(aes(y=ypoints[1], x=xpoints[1])) +
  geom_point(aes(y=ypoints[2], x=xpoints[2])) +
  geom_point(aes(y=ypoints[3], x=xpoints[3])) +
  geom_point(aes(y=ypoints[4], x=xpoints[4])) +
  geom_point(aes(y=ypoints[5], x=xpoints[5])) +
  geom_point(aes(y=ypoints[6], x=xpoints[6]))

但这是一种痛苦,而你正在寻求避免那种代码复制。答案取决于你在寻找什么。每个点的格式不同?试试这个:

ggplot(data = plot.df, aes(x = xvariable)) + 
  geom_line(aes(y = yvariable)) +
  geom_point(data=transform(plot.df, pointsID=as.factor(1:6)), 
             aes(y=ypoints, x=xpoints, color=pointsID))

您可以通过调用scale_colour_discrete和相关的ggplot组件来更改颜色(或其他格式参数的选项)。

PS - 您的原始策略失败,因为ggplot会等到打印时间来评估i中的xpoints[i]等参数;即使你看到1分,你实际上是将6个相同的点直接绘制在一起。

答案 2 :(得分:1)

虽然重新处理数据结构以避免像这样的循环是更好的答案,但有时你真的需要立即评估表达式,而不是关闭变量并稍后评估表达式。你可以使用ggplot2&#39; s aes_string()来做到这一点:

plot.test = ggplot(data = plot.df, aes(x = xvariable)) + 
  geom_line(aes(y = yvariable)) 

for (i in 1:6){
  plot.test = plot.test + geom_point(aes_string(y = ypoints[i], x = xpoints[i])) 
}

在这种情况下,您可以有效地对点值进行硬编码。也就是说,它相当于:

  plot.test = plot.test + geom_point(aes(y = 2, x = 3))

你也可以只对索引进行硬编码,并且以后仍然动态地引用ypoints和xpoints中的任何内容:

  plot.test = plot.test + geom_point(aes_string(y = paste0("ypoints[", i, "]"), x = paste0("xpoints[", i, "]"))) 

这是丑陋和笨拙的,有点黑客,但它有效,有时正是你所需要的,如果你不能出于任何原因自由地重新组织数据结构。