Построение двух переменных в виде линий с использованием ggplot2 на одном графике

240

Очень новичок, но скажу, что у меня есть такие данные:

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

Как я могу построить как временные ряды var0, так и var1 на одном и том же графике, с date на оси x, используя ggplot2? Бонусные очки, если вы делаете var0 и var1 разные цвета и можете включать легенду!

Я уверен, что это очень просто, но я не могу найти никаких примеров.

Теги:
ggplot2
time-series
graph
r-faq

5 ответов

323
Лучший ответ

Для небольшого количества переменных вы можете построить график вручную:

ggplot(test_data, aes(date)) + 
  geom_line(aes(y = var0, colour = "var0")) + 
  geom_line(aes(y = var1, colour = "var1"))
  • 1
    хороший пример, но как настроить мои собственные цвета (например, черный и оранжевый) ?, потому что кажется, что вы используете colour= качестве имени переменной.
  • 8
    Используйте шкалу ....
Показать ещё 2 комментария
313

Общий подход состоит в том, чтобы преобразовать данные в длинный формат (используя melt() из пакета reshape или reshape2) или gather() из пакета tidyr:

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

Изображение 4312

  • 6
    Вы также можете использовать функцию tidyr gather() пакета tidyr для tidyr данных: gather(test_data, variable, value, -date)
25

Вам нужно, чтобы данные были в "высоком" формате вместо "wide" для 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()

Изображение 4313

Просто чтобы очистить data, который ggplot потребляет после его прокладки через gather, выглядит следующим образом:

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
12

Использование ваших данных:

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() и reshape и reshape2 могут быть полезны, если у вас есть более сложные реальные данные, манипулировать.

После того, как данные находятся в этой сложной форме, для этого требуется только простой вызов ggplot() для создания сюжета, который вам нужен, со всеми дополнительными функциями (одна из причин, по которой пакеты построения более высокого уровня, такие как lattice и ggplot2, полезно):

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

Я оставлю это вам, чтобы привести в порядок ярлыки оси, название легенды и т.д.

НТН

  • 1
    Я думаю, что у вас есть неуместные парни в вашем коде там. Я думаю, что это то, что вы после: сложены <- с (test_data, data.frame (значение = c (var0, var1), переменная = фактор (rep (c ("Var0", "Var1"))), каждый = NROW (test_data), Dates = rep (date, 2))). Кроме того, какова цель столбца «каждый»? И разве это не просто более запутанный и менее эффективный способ расплавления данных, как показывает rcs? Я полагаю, я мог бы вообразить случай, когда melt не справился бы с работой, но это почти наверняка правильный инструмент для этой работы, если я что-то упустил?
  • 1
    @ chase, извините, Emacs ESS неправильно делает отступы. каждый из них является аргументом для rep() , поэтому мы получаем только 3 столбца в stacked . Я отредактирую код, чтобы сделать отступ более понятным.
Показать ещё 1 комментарий
1

Я также новичок в R, но, пытаясь понять, как работает ggplot, я думаю, у меня есть другой способ сделать это. Я просто поделюсь, вероятно, не как совершенное идеальное решение, а добавлю несколько разных точек зрения.

Я знаю, что ggplot лучше работает с фреймами данных, но иногда полезно знать, что вы можете напрямую построить два вектора без использования фрейма данных.

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

Длина вектора исходной даты равна 100, тогда как var0 и var1 имеют длину 50, поэтому я только отображаю доступные данные (первые 50 дат).

Изображение 4314

Однако я не смог добавить правильную легенду, используя этот формат. Кто-нибудь знает как?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню