【问题标题】:在同一张图上使用 ggplot2 将两个变量绘制为线
【发布时间】:2011-04-16 04:26:35
【问题描述】:

一个非常新的问题,但假设我有这样的数据:

test_data <-
  data.frame(
    var0 = 100 + c(0, cumsum(runif(49, -20, 20))),
    var1 = 150 + c(0, cumsum(runif(49, -10, 10))),
    date = seq(as.Date("2002-01-01"), by="1 month", length.out=100)
  )

如何使用ggplot2 在同一张图上绘制时间序列var0var1,并在x 轴上绘制date?如果您将var0var1 制作成不同的颜色,并且可以包含图例,则可以获得奖励积分!

我确定这很简单,但我找不到任何示例。

【问题讨论】:

    标签: r ggplot2 graph time-series r-faq


    【解决方案1】:

    对于少量的变量,可以自己手动建图:

    ggplot(test_data, aes(date)) + 
      geom_line(aes(y = var0, colour = "var0")) + 
      geom_line(aes(y = var1, colour = "var1"))
    

    【讨论】:

    • 很好的例子,但是如何自定义我自己的颜色(例如黑色和橙色)?,因为您似乎使用colour= 作为变量名。
    • 即使是 hadley 指定的 colour='var_names' 也可以正常工作。但是@DaveX - 如果想要选择特定颜色而不是通过函数自动选择颜色会更具体。
    • 如何添加图例?
    【解决方案2】:

    一般的方法是将数据转换为长格式(使用包reshapereshape2中的melt())或tidyr包中的gather()/pivot_longer()

    library("reshape2")
    library("ggplot2")
    
    test_data_long <- melt(test_data, id="date")  # convert to long format
    
    ggplot(data=test_data_long,
           aes(x=date, y=value, colour=variable)) +
           geom_line()
    

    另请参阅this question,了解将数据从宽改成长。

    【讨论】:

    • 也可以使用tidyr包的gather()函数来熔解数据:gather(test_data, variable, value, -date)
    【解决方案3】:

    对于 ggplot2,您需要数据采用“高”格式而不是“宽”格式。 “宽”意味着每行有一个观察,每个变量作为不同的列(就像你现在一样)。您需要将其转换为“高”格式,其中有一列告诉您变量的名称,另一列告诉您变量的值。从宽到高的过程通常被称为“融化”。您可以使用tidyr::gather 来融化您的数据框:

    library(ggplot2)
    library(tidyr)
    
    test_data <-
      data.frame(
        var0 = 100 + c(0, cumsum(runif(49, -20, 20))),
        var1 = 150 + c(0, cumsum(runif(49, -10, 10))),
        date = seq(as.Date("2002-01-01"), by="1 month", length.out=100)
      )
    test_data %>%
        gather(key,value, var0, var1) %>%
        ggplot(aes(x=date, y=value, colour=key)) +
        geom_line()
    

    为了清楚 ggplot 在通过 gather 管道后消耗的 data 看起来像这样:

    date        key     value
    2002-01-01  var0    100.00000
    2002-02-01  var0    115.16388 
    ...
    2007-11-01  var1    114.86302
    2007-12-01  var1    119.30996
    

    【讨论】:

      【解决方案4】:

      使用您的数据:

      test_data <- data.frame(
      var0 = 100 + c(0, cumsum(runif(49, -20, 20))),
      var1 = 150 + c(0, cumsum(runif(49, -10, 10))),
      Dates = seq.Date(as.Date("2002-01-01"), by="1 month", length.out=100))
      

      我创建了一个堆叠版本,这是 ggplot() 想要使用的:

      stacked <- with(test_data,
                      data.frame(value = c(var0, var1),
                                 variable = factor(rep(c("Var0","Var1"),
                                                       each = NROW(test_data))),
                                 Dates = rep(Dates, 2)))
      

      在这种情况下,生成 stacked 非常简单,因为我们只需要进行几次操作,但是如果您有更复杂的真实数据集来处理,reshape()reshapereshape2 可能会很有用操纵。

      一旦数据采用这种堆叠形式,它只需要一个简单的ggplot() 调用即可生成您想要的带有所有附加功能的绘图(这是latticeggplot2 等高级绘图包如此受欢迎的原因之一有用):

      require(ggplot2)
      p <- ggplot(stacked, aes(Dates, value, colour = variable))
      p + geom_line()
      

      我会留给你整理轴标签、图例标题等。

      HTH

      【讨论】:

      • 我认为您的代码中有一个放错位置的括号。我认为这就是你所追求的:stacked
      • @chase,抱歉,这是 Emacs ESS 的缩进错误。 each 是rep() 的一个参数,所以我们真的只在stacked 中得到3 个cols。我将编辑代码以使缩进更清晰。
      • @chase;您对melt() 的评论很好,我注意到 reshape[2] 包在这里很有用。我对 reshape2 不是很熟悉,对于这种简单的手动操作比调用melt() 更复杂,因为我不需要阅读如何使用melt(),所以工作量更少。当我在制作我的作品时,rcs 偷偷地回答了他的答案;当我开始回复时,没有任何答案。给猫剥皮的方法不止一种——正如他们所说! ;-)
      【解决方案5】:

      我也是 R 新手,但试图了解 ggplot 的工作原理,我想我有另一种方法来做到这一点。我只是分享可能不是一个完整的完美解决方案,而是添加一些不同的观点。

      我知道 ggplot 可以更好地处理数据帧,但有时知道您可以在不使用数据帧的情况下直接绘制两个向量可能也很有用。

      加载数据。原始日期向量长度为​​ 100,而 var0 和 var1 的长度为 50,所以我只绘制可用数据(前 50 个日期)。

      var0 <- 100 + c(0, cumsum(runif(49, -20, 20)))
      var1 <- 150 + c(0, cumsum(runif(49, -10, 10)))
      date <- seq(as.Date("2002-01-01"), by="1 month", length.out=50)    
      

      绘图

      ggplot() + geom_line(aes(x=date,y=var0),color='red') + 
                 geom_line(aes(x=date,y=var1),color='blue') + 
                 ylab('Values')+xlab('date')
      

      但是我无法使用这种格式添加正确的图例。有人知道怎么做吗?

      【讨论】:

      • 这增加了一个图例ggplot() + geom_line(aes(x=date,y=var0, group=1, colour = 'red')) + geom_line(aes(x=date,y=var1, group = 2, colour = 'blue')) + ylab('Values')+xlab('date')
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多