В R у меня есть фрейм данных с ценами спроса и предложения за один день. Вот пример:
TimeHM; Bid_Price1; Ask_Price1
08:12; 101; 102
08:13; 101; 102
08:14; 102; 104
...
17:05; 104; 105
Итак, каждая новая строка – это новая минута. Переменная TimeHM является символьной, а Bid_Price1 и Ask_Price1 — числовой.
Я хотел бы построить цены спроса и предложения за весь день и отметить «10:00» вертикальной линией. Вот мой код:
ggplot(MyData, aes(x=TimeHM)) +
geom_line(aes(y=Bid_Price1, group=1)) +
geom_line(aes(y=Ask_Price1, group=1)) +
geom_vline(xintercept = "10:00", color = "red", linetype = "dashed") +
xlab("Time") + ylab("Price") + theme_classic(base_size = 20)
Это работает (тоже вертикальная черта), и «group=1» тоже зачем-то нужна. Но проблема в том, что на оси X отмечается каждое наблюдение (за каждую минуту). Вместо этого я хочу обозначить некоторые конкретные моменты времени, например. 9:00; 12:00; 15:00.
Я пробовал разные решения с помощью Google. Я думаю, проблема в том, что он не видит TimeHM как время. Итак, перед ggplot я попробовал следующее:
MyData$TimeHM <- as.POSIXct(strptime(MyData$TimeHM, format = "%H:%M"))
Но потом почему-то добавляет сегодняшнюю дату, а потом использует время. Например, первая строка внезапно становится «25.07.2024 08:12:00». Затем я попытался добавить в ggplot одно из следующего:
#scale_x_datetime(labels = date_format("%H:%M"))
#scale_x_date(labels = date_format("%H:%M"))
#scale_x_datetime(labels = label_date("%H:%M"))
Это просто выдает мне ошибку. Каким-то образом мне однажды удалось построить график с помощью Scale_x_datetime, но обе кривые (бид и аск) были сдвинуты влево, так что первая цена была до 8:00 (а набор данных начинается после 8:00). Я также пробовал использовать as_hms.
Может ли кто-нибудь помочь? Как правильно это сделать?
Спасибо!
Если ваша ось X действительно имеет тип даты и времени, то так и должно быть scale_x_date(date_labels = "%H:%M")
Используйте mutate dplyr для преобразования TimeHM в дату и время в простом канале и Scales::label_time для форматирования меток в Scale_x_time():
library(ggplot2)
df <- data.frame(
TimeHM = c("08:12", "09:13", "10:14", "11:15"),
Bid_Price1 = c(100, 101, 102, 105),
Ask_Price1 = c(102, 103, 104, 106)
)
df |>
dplyr::mutate(TimeHM = as.POSIXct(TimeHM, format = "%H:%M", tz = "UTC")) |>
ggplot(aes(x = TimeHM)) +
geom_line(aes(y = Bid_Price1, group = 1), color = "#df2f9f") +
geom_line(aes(y = Ask_Price1, group = 1), color = "#106faf")+
geom_vline(xintercept = as.POSIXct("10:00", format = "%H:%M", tz = "UTC"), color = "red", linetype = "dashed")+
scale_y_continuous(limits = c(90, 110)) +
scale_x_time(
labels = scales::label_time(format = "%H:%M"),
breaks = as.POSIXct(c("09:00", "12:00", "15:00"), format = "%H:%M", tz = "UTC"),
limits = as.POSIXct(c("08:00", "15:59"), format = "%H:%M", tz = "UTC")
)
Приведите столбец времени к классу "POSIXct"
, а scale_x_datetime
позаботится о метках.
Что касается двух строк, то об этом уже спрашивали несколько раз. Проблемы такого типа обычно связаны с изменением формы данных. Формат должен быть длинным, а данные — широким форматом.
group
, другие (color
, linetype
) дополнительно дифференцируют линии и добавляют легенду к сюжету.MyData <- read.csv2(text = "TimeHM; Bid_Price1; Ask_Price1
08:12; 101; 102
08:13; 101; 102
08:14; 102; 104
17:05; 104; 105")
suppressPackageStartupMessages({
library(dplyr)
library(ggplot2)
})
x0 <- as.POSIXct(paste(Sys.Date(), "10:00"))
MyData %>%
mutate(TimeHM = as.POSIXct(paste(Sys.Date(), TimeHM))) %>%
tidyr::pivot_longer(-TimeHM) %>%
ggplot(aes(TimeHM, value, group = name)) +
geom_line() +
geom_vline(xintercept = x0, color = "red", linetype = "dashed") +
scale_x_datetime(date_breaks = "3 hours", date_labels = "%H:%M") +
xlab("Time") +
ylab("Price") +
theme_classic(base_size = 20)
Created on 2024-07-25 with reprex v2.1.0
Base R не имеет типа данных, зависящего только от времени. Просто тип даты и времени. Если что-то изменилось, убедитесь, что вы преобразуете значения в соответствии с текущим часовым поясом. У вас время указано в местном часовом поясе или в формате UTC? Вам будет проще помочь, если вы поделитесь данными в воспроизводимом формате, например
dput()
, чтобы мы могли скопировать/вставить данные в R для тестирования.