2013-01-23 18 views
5

Sto imparando R analizzando i risultati di una gara ciclistica e sto avendo problemi con i dati del tempo (quanto una persona ha preso per finire la gara).Come lavorare con tempi, distanze e velocità?

I dati dell'ora hanno il formato "HH: MM: SS".

Ho provato a convertirlo in posixct ma aggiunge un componente di data ad esso. Ho anche provato il pacchetto Chron ma non mi permette di dividere un numero per volta oggetto

Una delle cose che voglio fare è calcolare le velocità medie usando questo tempo, quindi devo essere in grado di dividere la distanza col tempo.

+3

convertirlo in secondi o più piccolo. La rappresentazione con ore e minuti è in realtà solo per la presentazione. –

+0

Potresti trovare utile il pacchetto 'lubridate' quando lavori con le date. C'è un PDF che descrive il pacchetto chiamato "Date and Times Made Easy with lubridate" pubblicato nel Journal of Statistical Software. Una rapida ricerca aumenterà. – rrs

risposta

5

Il pacchetto chron ha classi per gestire i tempi e la funzione da utilizzare è, attendere, times(). Ecco un esempio utilizzando tempi tipici per correre una maratona di serie:

library(chron) 
tms <- c("2:06:00", "3:34:30", "4:12:59") 
x <- times(tms) 

Ora avete un oggetto times, che rappresentano frazioni di un giorno.

str(x) 
Class 'times' atomic [1:3] 0.0875 0.149 0.1757 
    ..- attr(*, "format")= chr "h:m:s" 

È possibile eseguire calcoli di velocità, ma è necessario convertire la classe da dates a numerico con as.numeric.

dist <- 42.2 
as.numeric(dist/x/24) 
[1] 20.09524 11.80420 10.00856 

E ci sei: velocità in km/h.

5

Vorrei utilizzare POSIXct per il quale si dispone del supporto più potente in R base e pacchetti aggiuntivi.

Ogni volta che utilizzo dati intra-giornali per i quali la giornata non è importante, aggiungo solo una data di base, ad esempio, il 1 ° gennaio dell'anno corrente. Per tutti i confronti, le differenze, ecc questo lava fuori.

Anche di nota: as.numeric() di una variabile POSIXct si torna ai numeri normali (di seconds.subseconds dall'epoch) che è a portata di mano sia per l'aritmetica e in caso di necessità di memorizzare (in un db, senza datetime), o trasferire su un altro sistema o lingue. Ognuno ha un punto fluttuante --- e (frazionario) secondi da quando l'epoca è facile. POSIXct dà aggiunto benefici per la formattazione, sequenze, le differenze, tramando, ...

Ecco un piccolo esempio:

R> txt <- c("08:09:10", "09:10:11", "10:11:12", "11:12:13") 
R> times <- as.POSIXct(paste("2013-01-01", txt)) 
R> times 
[1] "2013-01-01 08:09:10 CST" "2013-01-01 09:10:11 CST" 
+ "2013-01-01 10:11:12 CST" "2013-01-01 11:12:13 CST" 
R> times - times[1] 
Time differences in secs 
[1]  0 3661 7322 10983 
attr(,"tzone") 
[1] "" 
R> as.numeric(times - times[1]) 
[1]  0 3661 7322 10983 
R> 
3

Quello che state vedendo non è davvero il momento, ma un tempo trascorso. Esistono tipi di dati per il tempo trascorso. Nella base R, la classe difftime fa questo.

tms <- c("2:06:00", "3:34:30", "4:12:59", "08:09:10", 
     "09:10:11", "10:11:12", "11:12:13") 

ta <- as.difftime(tms) 

che mostra come

> ta 
Time differences in hours 
[1] 2.100000 3.575000 4.216389 8.152778 9.169722 10.186667 11.203611 
attr(,"tzone") 
[1] "" 
> format(ta) 
[1] " 2.100000 hours" " 3.575000 hours" " 4.216389 hours" " 8.152778 hours" " 9.169722 hours" 
[6] "10.186667 hours" "11.203611 hours" 

Si può fare matematica con questo così convertendo a numerico.

> 42.2/as.numeric(ta) 
[1] 20.095238 11.804196 10.008564 5.176150 4.602102 4.142670 3.766643 

Il pacchetto lubridate ha anche tipi che si occupano di tempo trascorso, in particolare duration.

library("lubridate") 
ti <- as.duration(as.difftime(tms)) 

che mostra come

> ti 
[1] 7560s (~2.1 hours) 12870s (~3.58 hours) 15179s (~4.22 hours) 29350s (~8.15 hours) 
[5] 33011s (~9.17 hours) 36672s (~10.19 hours) 40333s (~11.2 hours) 

e si può fare la matematica con è dopo la conversione a numerico (qui, secondi invece di ore)

> 42.2/as.numeric(ti) 
[1] 0.005582011 0.003278943 0.002780157 0.001437819 0.001278362 0.001150742 0.001046290