2012-05-22 9 views
45

Supponiamo che io ho il seguente data.framefooore estratto e secondi da POSIXct a fini tramando in R

  start.time duration 
1 2012-02-06 15:47:00  1 
2 2012-02-06 15:02:00  2 
3 2012-02-22 10:08:00  3 
4 2012-02-22 09:32:00  4 
5 2012-03-21 13:47:00  5 

E class(foo$start.time) rendimenti

[1] "POSIXct" "POSIXt" 

mi piacerebbe creare un terreno di foo$duration v. foo$start.time. Nel mio scenario, sono interessato solo all'ora del giorno piuttosto che al giorno reale dell'anno. Come si fa ad estrarre l'ora del giorno come ore: secondi dalla classe di vettore POSIXct?

+1

le librerie 'lubridate' e' zoo' potrebbero essere utili per voi. ma in base R, 'format (foo $ start.time, format = '% H: M')'. – Justin

+0

Grazie. Un problema con 'format (foo $ start.time, format = '% H: M')' è che l'output è in formato carattere. Mi piacerebbe che l'output fosse in una sorta di formato numerico in modo che potesse essere usato come asse x di un grafico. – andrewj

+1

Ci sono molti modi. Ancora una volta ti indico a "lubridate" o [questo post] (http://stackoverflow.com/questions/7655514/how-do-i-plot-only-the-time-portion-of-a-timestamp- incluso-a-date) – Justin

risposta

39

Questa è una buona domanda ed evidenzia alcune delle difficoltà nell'affrontare le date in R. Il pacchetto lubridate è molto utile, quindi di seguito presenterò due approcci, uno basato sulla base (come suggerito da @ RJ-) e il altro usando il lubridato.

ricreare le (prime due righe) della dataframe nel post originale:

foo <- data.frame(start.time = c("2012-02-06 15:47:00", 
           "2012-02-06 15:02:00", 
           "2012-02-22 10:08:00"), 
        duration = c(1,2,3)) 

Convertire a POSIXct e la classe POSIXt (due modi per fare questo)

# using base::strptime 
t.str <- strptime(foo$start.time, "%Y-%m-%d %H:%M:%S") 

# using lubridate::ymd_hms 
library(lubridate) 
t.lub <- ymd_hms(foo$start.time) 

Ora, tempo di estratto come ore decimali

# using base::format 
h.str <- as.numeric(format(t.str, "%H")) + 
       as.numeric(format(t.str, "%M"))/60 

# using lubridate::hour and lubridate::minute 
h.lub <- hour(t.lub) + minute(t.lub)/60 

dimostrano che questi approcci sono uguali:

identical(h.str, h.lub) 

Quindi scegliere uno dei metodi di cui sopra per assegnare un'ora decimale foo$hr:

foo$hr <- h.str 

# If you prefer, the choice can be made at random: 
foo$hr <- if(runif(1) > 0.5){ h.str } else { h.lub } 

poi grafico usando il pacchetto ggplot2:

library(ggplot2) 
qplot(foo$hr, foo$duration) +  
             scale_x_datetime(labels = "%S:00") 
+0

Grazie per il suggerimento. Tuttavia, quando viene tracciato il grafico sopra riportato, considera ogni punto temporale come un'etichetta o una categoria anziché come un numero. In altre parole, i punti sono equidistanti sull'asse x. Contrastare la differenza con quanto segue, prendendo il 'foo' originale e quindi tracciando il seguente' foo $ start.time.numeric <- hour (pippo $ start.time) + minute (pippo $ start.time)/60' come ' con (foo, qplot (start.time.numeric, duration)) ' – andrewj

+0

@andrewj Ho aggiornato la mia risposta per rispondere a questo –

+1

In termini di problema, stai descrivendo, da questo post qui, http: // StackOverflow. it/questions/7655514/how-do-i-plot-only-the-time-of-a-timestamp-including-a-date, prova 'qplot (ora (pippo $ start.time) + minuto (foo $ start.time)/60, foo $ duration) + scale_x_datetime (labels = date_format ("% S: 00")) '. Sembra che la modifica di 'scale_x_datetime' abbia un parametro' labels'. – andrewj

14

si poteva contare su di base R:

# Using R 2.14.2 
# The same toy data 
foo <- data.frame(start.time = c("2012-02-06 15:47:00", 
           "2012-02-06 15:02:00", 
           "2012-02-22 10:08:00"), 
        duration = c(1,2,3)) 

Si nce class POSIXct contiene informazioni sulla data in modo strutturato, potete contare su substr per estrarre i caratteri nelle posizioni temporali all'interno del vettore POSIXct. Cioè, dato che si conosce il formato del vostro POSIXct (come sarebbe stato presentato in fase di stampa), è possibile estrarre ore e minuti:

# Extract hour and minute as a character vector, of the form "%H:%M" 
substr(foo$start.time, 12, 16) 

E poi incollarlo in una data arbitraria per riconvertirlo POSIXct. Nell'esempio utilizzo gennaio 2012, ma se non si specifica una data e invece si utilizza format R viene utilizzata la data corrente.

# Store time information as POSIXct, using an arbitrary date 
foo$time <- as.POSIXct(paste("2012-01-01", substr(foo$start.time, 12, 16))) 

Ed entrambi plot e ggplot2 sapere come formattare volte in POSIXct fuori dalla scatola.

# Plot it using base graphics 
plot(duration~time, data=foo) 

# Plot it using ggplot2 (0.9.2.1) 
library(ggplot2) 
qplot(x=time, y=duration, data=foo) 
5

Questo codice è molto più veloce di conversione in stringa e di nuovo a numerico

time <- c("1979-11-13T08:37:19-0500", "2014-05-13T08:37:19-0400"); 
time.posix <- as.POSIXct(time, format = "%Y-%m-%dT%H:%M:%S%z"); 
time.epoch <- as.vector(unclass(time.posix)); 
time.poslt <- as.POSIXlt(time.posix, tz = "America/New_York"); 
time.hour.new.york <- time.poslt$hour + time.poslt$min/60 + time.poslt$sec/3600; 

> time; 
[1] "1979-11-13T08:37:19-0500" "2014-05-13T08:37:19-0400" 
> time.posix; 
[1] "1979-11-13 15:37:19 IST" "2014-05-13 15:37:19 IDT" 
> time.poslt; 
[1] "1979-11-13 08:37:19 EST" "2014-05-13 08:37:19 EDT" 
> time.epoch; 
[1] 311348239 1399984639 
> time.hour.new.york; 
[1] 8.621944 8.621944 
2

Lubridate non gestisce temporali di dati al giorno, in modo da Hadley raccomanda il pacchetto HMS per questo tipo di dati. Qualcosa di simile potrebbe funzionare:

library(lubridate) 
foo <- data.frame(start.time = parse_datetime(c("2012-02-06 15:47:00", 
           "2012-02-06 15:02:00", 
           "2012-02-22 10:08:00")), 
        duration = c(1,2,3)) 


foo<-foo %>% mutate(time_of_day=hms::hms(second(start.time),minute(start.time),hour(start.time))) 

Attenzione per 2 potenziali problemi - 1) lubridate ha un diverso HMS funzione chiamata e 2) HMS :: HMS prende gli argomenti in ordine opposto a quello suggerito dal suo nome (in modo che possano essere forniti solo pochi secondi)

Problemi correlati