Накреслення двох змінних у вигляді рядків за допомогою ggplot2 на одному графіку


305

Дуже нове питання, але скажіть, у мене є такі дані:

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різних кольорів, і можуть включати легенду!

Я впевнений, що це дуже просто, але я не можу знайти жодного прикладу там.

Відповіді:


373

Для невеликої кількості змінних ви можете побудувати графік вручну самостійно:

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

3
приємний приклад, але як налаштувати власні кольори (наприклад, чорний і помаранчевий) ?, тому що, здається, ви використовуєте colour=як ім'я змінної.
ПК Дарвіна

1
навіть colour='var_names'як зазначено у хедлі, працює чудово. але @DaveX - буде більш конкретним, якщо потрібно вибрати конкретні кольори, а не автоматично обрані кольори за допомогою функції.
I_m_LeMarque

Як я можу додати до нього легенду?
користувач1700890

361

Загальний підхід полягає в перетворенні даних у тривалий формат (за допомогою melt()пакету reshapeабо reshape2) або gather()/ pivot_longer()з 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()

ggplot2 вихід

Дивіться також це питання щодо переформатування даних від широкого до довгого.


8
Ви також можете скористатися gather()функцією tidyrпакета для розплавлення даних:gather(test_data, variable, value, -date)
janosdivenyi

33

Вам потрібно, щоб дані були у форматі "високий" замість "широкого" для 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()

кілька серій ggplot2

Просто, щоб зрозуміти, 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

13

Використання даних:

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

Я залишу це вам, щоб виправити етикетки осей, назву легенди тощо.

HTH


1
Я думаю, що у вас в коді неправильно встановлені паролі. Я думаю, що це те, що ти шукаєш: stacked <- with (test_data, data.frame (значення = c (var0, var1), змінний = фактор (rep (c ("Var0", "Var1"))), every = NROW (test_data), Дати = повтор (дата, 2))). Також, яка мета стовпця "кожен"? І це не просто більш складний і менш ефективний спосіб плавлення даних, як показано на rcs? Я думаю, я міг би уявити собі приклад, коли розплав не виконає роботу, але це майже напевно правильний інструмент для цієї роботи, якщо я щось не пропускаю?
Чейз

1
@chase, вибачте, що Emacs ESS помилився з відступом. кожен - це аргумент rep(), тому ми насправді отримуємо лише 3 кол stacked. Я відредагую код, щоб зробити відступ більш зрозумілим.
Гевін Сімпсон

1
@chase; ваш коментар щодо melt()добре прийнятий, і зауважу, що пакет переформатування [2] був би корисним тут. Я не такий знайомий з reshape2, і для такої простої маніпуляції це робити вручну складніше, ніж виклик melt(), це було менше зусиль, тому що мені не потрібно було читати, як користуватися melt(). І РК підкрався своєю відповіддю, поки я виробляв свою; коли я почав відповідь, відповіді не було. більше, ніж один спосіб шкірити кота - як кажуть! ;-)
Гевін Сімпсон

7

Я також новачок у 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')

введіть тут опис зображення

Однак я не зміг додати правильну легенду за допомогою цього формату. Хтось знає як?


1
До цього додається легенда 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.