【问题标题】:Why does R behave differently when parsing parameters of plotting?为什么 R 在解析绘图参数时表现不同?
【发布时间】:2021-01-21 07:51:38
【问题描述】:

我正在尝试使用 ggplot 在单个折线图上绘制多个时间序列变量。我正在使用一个包含 n 个时间序列变量和一列时间段的 data.frame。本质上,我想遍历 data.frame,并将 n goem_lines 添加到单个图表中。

最初我尝试使用以下代码,其中;

  • df = data.frame 包含 n 个时间序列变量和 1 列时间段
  • wid = n(时间序列变量的数量)
  p <- ggplot() +
    scale_color_manual(values=c(colours[1:wid]))  
  for (i in 1:wid) {
    p <- p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
  } 
  ggplotly(p)

但是,这只会在 data.frame 中生成最终时间序列变量的图。然后我进一步调查,发现以下几组代码产生了完全不同的结果:

p <- ggplot() +
    scale_color_manual(values=c(colours[1:wid]))
i = 1
p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
i = 2
p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
i = 3
p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
  ggplotly(p)

Plot produced by code above

p <- ggplot() +
    scale_color_manual(values=c(colours[1:wid]))
p = p + geom_line(aes(x=df$Time, y=df[,1], color=var.lab[1]))
p = p + geom_line(aes(x=df$Time, y=df[,2], color=var.lab[2]))
p = p + geom_line(aes(x=df$Time, y=df[,3], color=var.lab[3]))
  ggplotly(p)

Plot produced by code above

在我看来,这两组代码是相同的,那么谁能解释一下为什么它们会产生如此不同的结果?

我知道这可能很容易使用 autoplot 完成,但我对这两个代码片段的行为更感兴趣。

【问题讨论】:

  • 实际绘图是在您打印时构建的(使用ggplotly)。只有这样才能评估i。顺便说一句,您的代码违反了 ggplot2 背后的几个原则。您应该以完全不同的方式处理此问题(即,您应该首先融化 data.frame)。
  • 你好,罗兰。谢谢,这就解释了!还要感谢有关违反原则的建议,这解释了为什么在某些情况下我会得到奇怪的结果。我会在 ggplot2 上做一些进一步的阅读以避免这些。
  • 您应该重塑您的数据,这样您就不需要进行多次geom_line 调用,而是进行一次调用。基本上,看看pivot_longer,这样你就可以有一个可以映射到color的变量
  • 感谢 csgroen 的建议:pivot_longer + 一些非常需要的关于 ggplot 的额外阅读正是我所需要的。

标签: r for-loop ggplot2 ggplotly


【解决方案1】:

您正在尝试做的是通过绘制多条线的“hack”方式,但在 ggplot 方面并不理想。为了成功,我会使用aes_string。但这是一个hack

df <- data.frame(Time = 1:20,
                 Var1 = rnorm(20),
                 Var2 = rnorm(20, mean = 0.5),
                 Var3 = rnorm(20, mean = 0.8))

vars <- paste0("Var", 1:3)
col_vec <- RColorBrewer::brewer.pal(3, "Accent")

library(ggplot2)
p <- ggplot(df, aes(Time))
for (i in 1:length(vars)) {
    p <- p + geom_line(aes_string(y = vars[i]), color = col_vec[i], lwd = 1)
}
p + labs(y = "value")

如何正确操作

为了使这个绘图更正确,您需要先对数据进行透视,以便将每个美学 (aes) 映射到数据框中的一个变量。这意味着我们需要一个变量在我们的数据框中是color。因此,我们pivot_longer 并再次绘制:

library(tidyr)
df_melt <- pivot_longer(df, cols = Var1:Var3, names_to = "var")

ggplot(df_melt, aes(Time, value, color = var)) +
    geom_line(lwd = 1) +
    scale_color_manual(values = col_vec)

【讨论】:

  • 谢谢 - 这正是我想要完成的。我使用 R 已经有一段时间了,但这是我第一次真正玩弄事物的视觉方面,所以非常感谢你为我指明了正确的方向。
  • 我感觉到你了。 ggplot 具有非常独特的语法和“逻辑”,许多非常精通基本 R 的人必须“重新思考”如何完成事情以适应其逻辑。一开始,它似乎违反直觉,但我认为当你努力弄清楚它时它会变得相当优雅
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 2012-05-11
相关资源
最近更新 更多