ChatGPT解决这个技术问题 Extra ChatGPT

在同一张图上使用 ggplot2 将两个变量绘制为线

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

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 不同的颜色,可以加分,并且可以包括一个图例!

我敢肯定这很简单,但我找不到任何例子。


N
Nakx

对于少量变量,您可以自己手动构建绘图:

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 - 如果一个人想要选择特定的颜色而不是通过函数自动选择颜色,那会更具体。
如何为其添加图例?
@user1700890,图例好像是自动添加的
A
Axeman

一般方法是将数据转换为长格式(使用包 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()

https://i.stack.imgur.com/qkaZR.png

另请参阅 this question,了解如何将数据从宽变长。


您也可以使用 tidyr 包的 gather() 函数来融合数据:gather(test_data, variable, value, -date)
R
RubenLaguna

对于 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()

https://i.stack.imgur.com/7ji3z.png

只是为了清楚 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

G
Gavin Simpson

使用您的数据:

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()

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

高温高压


我认为您的代码中有一个放错位置的括号。我认为这就是你所追求的:stacked <- with(test_data, data.frame(value = c(var0, var1), variable = factor(rep(c("Var0", "Var1"))), each = NROW(测试数据),日期 = 代表(日期,2)))。另外,“每个”列的目的是什么?这不只是 rcs 所示的一种更复杂且效率更低的数据融合方式吗?我想我可以想象一个例子,melt 无法完成工作,但它几乎肯定是完成这项工作的正确工具,除非我遗漏了什么?
@chase,对不起,那是 Emacs ESS 缩进错误。 each 是 rep() 的一个参数,所以我们真的只在 stacked 中得到 3 个 cols。我将编辑代码以使缩进更清晰。
@追赶;您对 melt() 的评论很好,我注意到 reshape[2] 包在这里很有用。我对 reshape2 不是很熟悉,对于这种简单的手动操作比调用 melt() 更复杂,因为我不需要阅读如何使用 melt(),所以工作量更少。当我在制作我的作品时,rcs 偷偷地回答了他的答案;当我开始回复时,没有任何答案。给猫剥皮的方法不止一种——正如他们所说! ;-)
s
susopeiz

我也是 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')

https://i.stack.imgur.com/M1Dhv.png

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


这会添加一个图例 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')
除了您的没有传说之外,这与公认的答案有什么区别?
@camille 如所示,唯一的区别是这种方式不使用数据框作为输入,只是直接使用向量

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅