【问题标题】:adding layers in ggplot2 with for loops使用 for 循环在 ggplot2 中添加层
【发布时间】:2021-04-29 15:39:09
【问题描述】:

我想这很容易,但我不明白。它与在 gg​​plots 上使用 for 循环有关。 问题是:为什么下面这两个代码给出不同的结果?看起来好像在带有循环的代码上,只考虑了第二次迭代,但我不知道为什么。 潜在的问题是:是否可以使用 ggplot2 对象运行这样的循环? 非常感谢你的帮助, 大卫

# Code 1

aux <- 3:4
p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point()

for (i in 1:2)
 
p <-  p + geom_segment(aes(x = aux[i], y = 0, xend = aux[i], yend = 35), colour = "purple")


# Code 2

p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point()

p <- p + geom_segment(aes(x = aux[1], y = 0, xend = aux[1], yend = 35), colour = "purple")

p <- p + geom_segment(aes(x = aux[2], y = 0, xend = aux[2], yend = 35), colour = "purple")

【问题讨论】:

  • 感谢格雷戈尔的编辑,

标签: r for-loop ggplot2


【解决方案1】:

ggplot 会进行一些惰性求值,因此在您的for 循环示例中i 不会立即求值。如果我们查看这些层,我们可以看到i 仍然存在为i,而不是34 在各自的迭代中。当您打印绘图时,即评估 i 时 - 在您打印绘图时采用的任何值。什么时候甚至可以在循环后更改i 导致问题:

aux <- 3:4
p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point()

for (i in 1:2) {
  p <-  p + geom_segment(aes(x = aux[i], y = 0, xend = aux[i], yend = 35), colour = "purple")
}
  
p$layers
# [[1]]
# geom_point: na.rm = FALSE
# stat_identity: na.rm = FALSE
# position_identity 
# 
# [[2]]
# mapping: x = ~aux[i], y = 0, xend = ~aux[i], yend = 35 
# geom_segment: arrow = NULL, arrow.fill = NULL, lineend = butt, linejoin = round, na.rm = FALSE
# stat_identity: na.rm = FALSE
# position_identity 
# 
# [[3]]
# mapping: x = ~aux[i], y = 0, xend = ~aux[i], yend = 35 
# geom_segment: arrow = NULL, arrow.fill = NULL, lineend = butt, linejoin = round, na.rm = FALSE
# stat_identity: na.rm = FALSE
# position_identity 

## changing `i` later can still cause problems:
i = 5
print(p)
# Warning messages:
# 1: Removed 32 rows containing missing values (geom_segment). 
# 2: Removed 32 rows containing missing values (geom_segment). 

所以,不,你不能真的像那样使用for 循环。可能有一些解决方法,但这感觉像是一个 XY 问题 - 这不是 ggplot 的用途,因此以这种方式使用它会很困难。

很难知道您的真实用例是什么,但在这种情况下,我们可以将aux 数据放入数据框中并像这样(ggplot 可用于数据框):

ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  geom_segment(
    data = data.frame(aux),
    aes(x = aux, xend = aux),
    y = 0, yend = 35, colour = "purple"
  )

不过,对于垂直线的特殊情况,我们可以直接使用geom_vlineaux 向量:

ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  geom_vline(xintercept = aux, colour = "purple")

【讨论】:

  • 非常感谢格雷戈尔。使用 aux 作为 data.frame 就可以了。我什至没有考虑过,非常感谢。我的真实数据比我发布的要复杂一点,所以我需要使用段,而不是 vlines。再次感谢,
  • 会的。不知道。谢谢。最好的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-19
  • 2015-05-12
  • 2022-01-02
  • 1970-01-01
相关资源
最近更新 更多