Даты с месяцем и днем ​​в графике временных рядов в ggplot2 с фасеткой на годы

Я хочу иметь как month, так и day по оси x графика временных рядов при использовании facet в течение лет в ggplot2. Мой MWE ниже:

set.seed(12345)
Date <- seq(as.Date("2010/1/1"), as.Date("2014/1/1"), "week")
Y <- rnorm(n=length(Date), mean=100, sd=1)
df <- data.frame(Date, Y)

df$Year <- format(df$Date, "%Y")
df$Month <- format(df$Date, "%b")
df$Day <- format(df$Date, "%d")

df$MonthDay <- format(df$Date, "%d-%b")


p <- ggplot(data=df, mapping=aes(x=MonthDay, y=Y, shape=Year, color=Year)) + geom_point() +geom_line(aes(group = 1))
p <- p + facet_grid(facets = Year ~ ., margins = FALSE) + theme_bw()
print(p)

enter image description here

Я попытался управлять метками оси x со следующей командой

p + scale_y_continuous() + scale_x_date(labels = date_format("%d-%b"))

Но он выдает следующее сообщение об ошибке.

Error: Invalid input: date_trans works with objects of class Date only

Любая помощь для решения этой проблемы будет высоко оценена. Заранее благодарим за помощь.

Ответ 1

Вы очень близки. Вы хотите, чтобы ось x была мерилом того, где вы находитесь в году, но у вас есть ее как вектор-символ, и поэтому вы получаете каждую отмеченную точку. Если вы вместо этого представляете непрерывную переменную, это может привести к лучшим результатам. Одной непрерывной переменной будет день года.

df$DayOfYear <- as.numeric(format(df$Date, "%j"))
ggplot(data = df,
       mapping = aes(x = DayOfYear, y = Y, shape = Year, colour = Year)) +
  geom_point() +
  geom_line() +
  facet_grid(facets = Year ~ .) +
  theme_bw()

enter image description here

Ось может быть отформатирована более по дате с соответствующей функцией метки, но перерывы все еще не найдены с учетом даты. (И кроме того, есть проблема NA.)

ggplot(data = df,
       mapping = aes(x = DayOfYear, y = Y, shape = Year, colour = Year)) +
  geom_point() +
  geom_line() +
  facet_grid(facets = Year ~ .) +
  scale_x_continuous(labels = function(x) format(as.Date(as.character(x), "%j"), "%d-%b")) +
  theme_bw()

enter image description here

Чтобы получить хорошее представление о прекрасных датах, можно использовать другую переменную. Тот, который имеет тот же день в году, что и исходные данные, но всего один год. В этом случае 2000 год, так как это был високосный год. Проблемы с этим в основном связаны с високостными днями, но если вас это не волнует (1 марта непикового года будет совпадать с 29 февраля високосного года и т.д.), Вы можете использовать:

df$CommonDate <- as.Date(paste0("2000-",format(df$Date, "%j")), "%Y-%j")
ggplot(data = df,
       mapping = aes(x = CommonDate, y = Y, shape = Year, colour = Year)) +
  geom_point() +
  geom_line() +
  facet_grid(facets = Year ~ .) +
  scale_x_date(labels = function(x) format(x, "%d-%b")) +
  theme_bw()

enter image description here

Ответ 2

Приклеивание кода @MYaseen208 для создания данных.

При построении графика используйте x = Date и используйте ниже

p <- ggplot(data = df, aes(x = Date, y = Y, shape = Year, color = Year)) +
  geom_point() + geom_line(aes(group = 1))
  #adding facet and using facet_wrap with free x scales
  p <- p + facet_wrap(~Year,ncol=1, scales = "free_x") + theme_bw()+
scale_y_continuous() + 
scale_x_date(labels = date_format("%d-%b"), breaks = date_breaks("2 weeks")) +
 theme(axis.text.x = element_text(angle = 90, vjust = 0.5, size = 8))

Я использовал facet_wrap, чтобы получить свободные масштабы x_axis. Когда вы разделяете данные, мы не можем получить одну и ту же комбинацию день-месяц за каждый год.

enter image description here

Ответ 3

Это похоже на это... Я просто создал метки...

library("ggplot2")
library("scales")
set.seed(12345)
Date <- seq(as.Date("2010/1/1"), as.Date("2014/1/1"), "week")
Y <- rnorm(n=length(Date), mean=100, sd=1)
df <- data.frame(Date, Y)

df$Year <- format(df$Date, "%Y")
df$Month <- format(df$Date, "%b")
df$Day <- format(df$Date, "%d")

df$MonthDay <- format(df$Date, "%d-%b")
df$MonthDay2 <- df$MonthDay
# only show every third label... otherwise it too crowded
df$MonthDay2[as.numeric(row.names(df))%%3!=0] <- ""
labels <- df$MonthDay2

p <- ggplot(data=df, mapping=aes(x=MonthDay, y=Y, shape=Year, color=Year)) + geom_point() +geom_line(aes(group = 1))
p <- p + facet_grid(facets = Year ~ ., margins = FALSE) + theme_bw()
p + scale_y_continuous() + scale_x_discrete(labels=labels) + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, size = 8))

plot

Ответ 4

Модификация подхода @Brian Diggs, который сохраняет исходный день и месяц (1 марта сохраняется 1 марта, а не 29 февраля) заключается в принуждении даты в строку, а затем заменить год:

library(lubridate)
library(stringr)
df$CommonDate <- ymd(paste0("2000-",str_sub(as.character(df$Date),-5)))

Затем вы можете продолжить:

ggplot(data = df,
   mapping = aes(x = CommonDate, y = Y, shape = Year, colour = Year)) +
  geom_point() +
  geom_line() +
  facet_grid(facets = Year ~ .) +
  scale_x_date(labels = function(x) format(x, "%d-%b")) +
  theme_bw()