Vẽ hai biến là các dòng sử dụng ggplot2 trên cùng một biểu đồ


305

Một câu hỏi rất mới, nhưng nói rằng tôi có dữ liệu như thế này:

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

Làm cách nào tôi có thể vẽ cả chuỗi thời gian var0var1trên cùng một biểu đồ, với datetrục x, bằng cách sử dụng ggplot2? Điểm thưởng nếu bạn thực hiện var0var1màu sắc khác nhau, và có thể bao gồm một huyền thoại!

Tôi chắc chắn rằng điều này rất đơn giản, nhưng tôi không thể tìm thấy bất kỳ ví dụ nào ngoài đó.

Câu trả lời:


373

Đối với một số lượng nhỏ các biến, bạn có thể tự xây dựng cốt truyện:

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

3
ví dụ đẹp, nhưng làm thế nào để tùy chỉnh màu của riêng tôi (Ví dụ: đen và cam)?, vì có vẻ như bạn đang sử dụng colour=làm tên biến.
Darwin PC

1
ngay cả colour='var_names'khi được chỉ định bởi hadley hoạt động tốt. nhưng @DaveX - sẽ cụ thể hơn nếu người ta muốn chọn các màu cụ thể thay vì tự động chọn các màu theo chức năng.
I_m_LeMarque

Làm thế nào tôi có thể thêm một huyền thoại cho nó?
dùng1700890

361

Cách tiếp cận chung là chuyển đổi dữ liệu sang định dạng dài (sử dụng melt()từ gói reshapehoặc reshape2) hoặc gather()/ pivot_longer()từ tidyrgói:

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

đầu ra ggplot2

Cũng xem câu hỏi này về việc định hình lại dữ liệu từ rộng đến dài.


8
Bạn cũng có thể sử dụng gather()chức năng của tidyrgói để làm tan dữ liệu:gather(test_data, variable, value, -date)
janosdivenyi

33

Bạn cần dữ liệu ở định dạng "cao" thay vì "rộng" cho ggplot2. "Rộng" có nghĩa là có một quan sát trên mỗi hàng với mỗi biến là một cột khác nhau (như bạn có bây giờ). Bạn cần chuyển đổi nó sang định dạng "cao" trong đó bạn có một cột cho bạn biết tên của biến và một cột khác cho bạn biết giá trị của biến. Quá trình chuyển từ rộng sang cao thường được gọi là "tan chảy". Bạn có thể sử dụng tidyr::gatherđể làm tan khung dữ liệu của mình:

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

nhiều loạt ggplot2

Chỉ cần được rõ ràng datarằng ggplotđược tiêu thụ sau khi đường ống nó qua gathervẻ bề ngoài như thế này:

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

13

Sử dụng dữ liệu của bạn:

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

Tôi tạo một phiên bản xếp chồng, đó là những gì ggplot()muốn làm việc với:

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

Trong trường hợp này sản xuất stackedlà khá dễ dàng vì chúng tôi chỉ phải làm một vài thao tác, nhưng reshape()reshapereshape2có thể có ích nếu bạn có một phức tạp hơn bộ dữ liệu thực tế để thao tác.

Khi dữ liệu ở dạng xếp chồng này, nó chỉ yêu cầu một ggplot()cuộc gọi đơn giản để tạo ra âm mưu bạn muốn với tất cả các tính năng bổ sung (một lý do tại sao các gói âm mưu cấp cao hơn thích latticeggplot2rất hữu ích):

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

Tôi sẽ để lại cho bạn để thu dọn nhãn trục, tiêu đề huyền thoại, v.v.

HTH


1
Tôi nghĩ rằng bạn có một parens đặt sai vị trí trong mã của bạn trên đó. Tôi nghĩ đây là những gì bạn đang có sau: xếp chồng <- với (test_data, data.frame (value = c (var0, var1), biến = Fact (rep (c ("Var0", "Var1"))), mỗi = NROW (test_data), Ngày = rep (ngày, 2))). Ngoài ra, mục đích của cột "mỗi" là gì? Và đây không chỉ là một cách phức tạp hơn và kém hiệu quả hơn để làm tan chảy dữ liệu như được hiển thị bởi rcs? Tôi đoán tôi có thể tưởng tượng một trường hợp mà tan chảy sẽ không hoàn thành công việc, nhưng nó gần như chắc chắn là công cụ phù hợp cho công việc này trừ khi tôi thiếu một cái gì đó?
Đuổi theo

1
@chase, xin lỗi, đó là Emacs ESS bị thụt lề sai. mỗi cái là một đối số rep(), vì vậy chúng tôi thực sự chỉ nhận được 3 cols stacked. Tôi sẽ chỉnh sửa mã để làm cho thụt lề rõ ràng hơn.
Gavin Simpson

1
@săn bắt; nhận xét của bạn melt()được thực hiện tốt và tôi lưu ý rằng gói định hình lại [2] sẽ hữu ích ở đây. Tôi không quen thuộc với reshape2 và vì một thao tác đơn giản như vậy thực hiện bằng tay phức tạp hơn so với một cuộc gọi đến melt(), nó đã ít nỗ lực hơn vì tôi không cần phải đọc cách sử dụng melt(). Và rcs lẻn vào với câu trả lời của anh ấy trong khi tôi đang sản xuất của tôi; Khi tôi bắt đầu trả lời, không có câu trả lời. nhiều hơn một cách để lột da một con mèo - như họ nói! ;-)
Gavin Simpson

7

Tôi cũng mới biết về R nhưng cố gắng hiểu ggplot hoạt động như thế nào, tôi nghĩ rằng tôi có một cách khác để làm điều đó. Tôi chỉ chia sẻ có lẽ không phải là một giải pháp hoàn hảo hoàn hảo mà là để thêm một số quan điểm khác nhau.

Tôi biết ggplot được tạo ra để hoạt động với datafram tốt hơn nhưng đôi khi cũng có thể hữu ích khi biết rằng bạn có thể vẽ trực tiếp hai vectơ mà không cần sử dụng dataframe.

Đang tải dữ liệu. Độ dài vectơ ngày ban đầu là 100 trong khi var0 và var1 có độ dài 50 vì vậy tôi chỉ vẽ đồ thị dữ liệu có sẵn (50 ngày đầu tiên).

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)    

Âm mưu

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

nhập mô tả hình ảnh ở đây

Tuy nhiên tôi không thể thêm một chú thích chính xác bằng định dạng này. Có ai biết làm thế nào không?


1
Điều này thêm một huyền thoại 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')
flurbius
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.