2015-04-30 17 views
10

voglio avere sia month e day in asse x del grafico temporale quando si utilizza facet per anni in ggplot2. Il mio MWE è qui sotto:date con il mese e il giorno in grafico temporale in ggplot2 con sfaccettatura per anni

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

ho cercato di controllare le etichette di asse x con il seguente comando

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

Ma getta il seguente messaggio di errore.

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

Qualsiasi aiuto per risolvere questo problema sarà molto apprezzato. Grazie in anticipo per il vostro aiuto.

+0

Grazie @ G.Grothendieck per il tuo commento e mostrando interesse per il mio problema. L'uso di 'x = Date' avrà inutilmente tutti e quattro gli anni nell'asse x che non è richiesto. – MYaseen208

risposta

16

si è molto vicini. Vuoi che l'asse x sia una misura di dove sei nell'anno, ma lo hai come vettore di carattere e così ottieni ogni singolo punto etichettato. Se invece si crea una variabile continua, si potrebbero ottenere risultati migliori. Una variabile continua sarebbe il giorno dell'anno.

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

L'asse potrebbe essere formattato più data-come con una funzione etichetta appropriata, ma le interruzioni sono ancora non essere trovato in modo molto data-consapevole. (E per di più, c'è un NA problema pure.)

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

Per ottenere la bontà delle belle pause data, una variabile diversa può essere utilizzato. Uno che ha lo stesso giorno dell'anno dei dati originali, ma solo un anno. In questo caso, 2000 poiché era un anno bisestile. I problemi con questo hanno più a che fare con i giorni bisestili, ma se non ti interessa (il 1 ° marzo di un anno non bisestile si allineerà con il 29 febbraio di un anno bisestile, ecc.) È possibile utilizzare:

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

+0

Ottima risposta. @ Brian, avere dati giornalieri per diversi anni e voler tracciare anni uno sopra l'altro mi sembra un compito molto comune. Sei a conoscenza di un pacchetto che accetta una variabile data, utilizza l'approccio "CommonDate" senza il problema dei giorni bisestili? – Dan

+1

@Dan Spiacente, non conosco un pacchetto che lo faccia. Ci sono parecchie date parziali/tempi parziali che sarebbero utili in contesti come questi, ma non so di dove siano stati raccolti. –

3

Questo sembra farlo ... Ho appena creato manualmente le etichette ...

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

+0

Grazie a @cory per la bella soluzione. (+1) – MYaseen208

+1

qualcun altro ha sbagliato le date con questo? Mi sono convertito tutti al 2015 .. – infominer

+0

Scelta eccellente @ infominer. – MYaseen208

6

Attaccando con il codice @ MYaseen208 per la creazione di dati.

Quando si stampa esso uso x = Date e utilizzare il sotto

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

ho usato facet_wrap, per ottenere scale x_axis liberi. Quando dividi i tuoi dati, non possiamo ottenere la stessa combinazione giorno-mese per ogni anno.

enter image description here

0

Una modifica approccio @ Brian Diggs' che conserva il giorno originale e il mese (1 marzo è conservato come 1 marzo anziché 29 febbraio) è quello di costringere la data in una stringa, quindi sostituire l'anno:

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

si può quindi procedere con:

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