2017-07-13 2 views
1

J'ai un dataframe qui ressemble à ceci:Calcul de la durée cumulative de R

 POI LOCAL.DATETIME 
1 1  2017-07-11 15:02:13 
2 1  2017-07-11 15:20:28 
3 2  2017-07-11 15:20:31 
4 2  2017-07-11 15:21:13 
5 3  2017-07-11 15:21:18 
6 3  2017-07-11 15:21:21 
7 2  2017-07-11 15:21:25 
8 2  2017-07-11 15:21:59 
9 1  2017-07-11 15:22:02 
10 1  2017-07-11 15:22:05 

Je veux être en mesure de calculer (probablement avec lubridate) le temps cumulé passé à chaque point d'intérêt et de les combiner dans une table ressemble à quelque chose comme ceci:

 POI TOTAL.TIME 
1 1  00:18:18 
2 2  00:01:11 
3 3  00:00:03 

aussi, je ne suis pas sûr de savoir comment traiter avec le temps entre les points d'intérêt, comme les 3 secondes entre les lignes 2 et 3. Je pense que peut-être que je dois calculer le temps de la ligne 1 à rangée 3 au lieu de rangée 1 à rangée 2.

Répondre

2

Pour obtenir le temps total dans les périodes de chaque groupe, vous devez d'abord créer un index de groupe. J'utilise rleid à partir de data.table Vous pouvez ensuite calculer le temps total passé dans chacun de ces groupes, puis résumer par le POI initial en utilisant sum.

df <- read.table(text="  POI LOCAL.DATETIME 
1  '2017-07-11 15:02:13' 
1  '2017-07-11 15:20:28' 
2  '2017-07-11 15:20:31' 
2  '2017-07-11 15:21:13' 
3  '2017-07-11 15:21:18' 
3  '2017-07-11 15:21:21' 
2  '2017-07-11 15:21:25' 
2  '2017-07-11 15:21:59' 
1  '2017-07-11 15:22:02' 
1  '2017-07-11 15:22:05'", 
       header=TRUE,stringsAsFactors=FALSE) 
df$LOCAL.DATETIME <- as.POSIXct(df$LOCAL.DATETIME) 

library(dplyr) 
df%>% 
    mutate(grp=data.table::rleid(POI))%>% 
    group_by(grp)%>% 
    summarise(POI=max(POI),TOTAL.TIME=difftime(max(LOCAL.DATETIME), 
            min(LOCAL.DATETIME),units="secs"))%>% 
    group_by(POI)%>% 
    summarise(TOTAL.TIME=sum(TOTAL.TIME)) 

# A tibble: 3 × 2 
    POI TOTAL.TIME 
    <int>  <time> 
1  1 1098 secs 
2  2 76 secs 
3  3  3 secs 

Pour obtenir minute et seconde, vous pouvez utiliser as.period de lubridate:

library(lubridate) 
df%>% 
    mutate(grp=data.table::rleid(POI))%>% 
    group_by(grp)%>% 
    summarise(POI=max(POI),TOTAL.TIME=difftime(max(LOCAL.DATETIME), 
            min(LOCAL.DATETIME),units="secs"))%>% 
    group_by(POI)%>% 
    summarise(TOTAL.TIME=sum(TOTAL.TIME))%>% 
    mutate(TOTAL.TIME =as.period((TOTAL.TIME), unit = "sec")) 

    POI TOTAL.TIME 
    <int> <S4: Period> 
1  1  18M 18S 
2  2  1M 16S 
3  3   3S 
+0

a pas cette méthode va prendre la ligne 10 - ligne 1, ligne 8 - ligne 3, et rangée 6 - rangée5? Je dois être capable de faire (ligne 2 - ligne 1) + (ligne 10 - ligne 9), etc. – Sam

+0

@Sam Oui, j'ai édité ma réponse pour le faire. –

+0

@P Lapointe Merci beaucoup, c'est exactement ce que je cherchais. – Sam

0

Une autre option data.table est de créer des groupes de 2 lignes pour chaque POI, prendre la différence de temps entre eux, et enfin résumer par POI:

library(data.table) 

dt <- as.data.table(df) 
dt[, grp2 := (seq_len(.N)+1) %/% 2, by = POI] 
dt[, time_diff := difftime(LOCAL.DATETIME, shift(LOCAL.DATETIME), unit = "min"), by = .(POI, grp2)] 
dt[ , .(TOTAL.TIME = sum(time_diff, na.rm = T)), by = POI] 

# POI  TOTAL.TIME 
#1: 1 18.300000 mins 
#2: 2 1.266667 mins 
#3: 3 0.050000 mins