3 votes

Comment dupliquer des lignes en R et ajouter de nouvelles données?

J'ai un data.table de données de timestamp qui comprend à la fois l'heure de début et l'heure de fin pour les personnes, arrondies aux intervalles de 15 minutes les plus proches. Je veux pouvoir dupliquer chaque ligne pour avoir le même nombre de copies que le nombre d'intervalles de 15 minutes couverts par leurs données d'entrée/sortie, tout en ajoutant une nouvelle colonne qui répertorie l'intervalle de 15 minutes (par exemple, une personne pointant à 10h00 et partant à 11h00, il y aurait quatre lignes créées, une avec l'heure indiquée à 10h00, une à 10h15, une à 10h30 et une à 10h45).

3voto

Chabo Points 1385

Je n'ai aucune idée de ce à quoi ressemble vos données, mais voici ce que j'ai compris.

library(padr)
library(zoo)

#données
utilisateur<-"4"
heures<-c("10:00","11:15")
heures<-as.POSIXct(heures,format="%H:%M")

#créer un data frame
dt<-data.frame(utilisateur,heures)

> dt
  utilisateur               heures
1    4 2018-05-31 10:00:00
2    4 2018-05-31 11:15:00

#ajuster les intervalles
dt<-pad(dt, interval="15 min")

#propager l'identifiant utilisateur
dt<-na.locf(dt)

>dt

  utilisateur               heures
1    4 2018-05-31 10:00:00
2    4 2018-05-31 10:15:00
3    4 2018-05-31 10:30:00
4    4 2018-05-31 10:45:00
5    4 2018-05-31 11:00:00
6    4 2018-05-31 11:15:00

0voto

AdamO Points 2531

C'est en fait juste une application très simple de la transposition et de la dernière observation reportée.

Voici mon employé:

emp <- data.frame(empid = 001, timein = as.POSIXct('2018-05-31 8:00'), timeout = as.POSIXct('2018-05-31 17:00'))

Voici mon wrapper de dernière observation reportée (mais il y a aussi zoo::na.locf)

locf <- function(y) c(NA, na.omit(y))[cumsum(!is.na(y))+1]

Maintenant transposer:

emplong <- reshape(emp, direction='long', idvar='empid', varying=list(2:3), 
  times=c('in', 'out'), timevar='status')

Cela donne:

      empid status              timein
1.in      1     in 2018-05-31 08:00:00
1.out     1    out 2018-05-31 17:00:00

Créez maintenant un planning:

roster <- data.frame('times' = seq(
  from=as.POSIXct('2018-05-31 00:00:00'),
  to=as.POSIXct('2018-06-01 00:00:00'),
  by=15*60))

Et fusionnez:

roster <- merge(roster, emplong[, -1], by.x='times', by.x='timein', all=T)

Et LOCF

roster$status <- locf(roster$status )
roster$status[is.na(roster$status )] <- 'out'

Cela donne:

> roster
                 times status
1  2018-05-31 00:00:00    out
2  2018-05-31 00:15:00    out
3  2018-05-31 00:30:00    out
4  2018-05-31 00:45:00    out
5  2018-05-31 01:00:00    out
...
31 2018-05-31 07:30:00    out
32 2018-05-31 07:45:00    out
33 2018-05-31 08:00:00     in
34 2018-05-31 08:15:00     in
...
67 2018-05-31 16:30:00     in
68 2018-05-31 16:45:00     in
69 2018-05-31 17:00:00    out
70 2018-05-31 17:15:00    out

0voto

Luke C Points 7207

Pour une solution data.table, en supposant que votre data.table est formatée comme ceci :

library(data.table)

dt <- data.table(
  employee = c("John", "Paul", "Mary"),
  clock.in = as.POSIXct(c("10:30", "12:30", "13:15"), format = "%R"),
  clock.out = as.POSIXct(c("11:00", "13:15", "14:15"), format = "%R")
                 )

> dt
   employee            clock.in           clock.out
1:     John 2018-05-31 10:30:00 2018-05-31 11:00:00
2:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00
3:     Paul 2018-05-31 12:30:00 2018-05-31 13:15:00

Utilisez setkey pour permettre une jointure entre la table de base et une table où une séquence d'intervalle de 15 minutes est créée entre les heures de pointage de début et de fin :

setkey(dt, employee)

> dt[dt[, seq.POSIXt(clock.in, clock.out, by = 60*15), by = employee]]
    employee            clock.in           clock.out                  V1
 1:     John 2018-05-31 10:30:00 2018-05-31 11:00:00 2018-05-31 10:30:00
 2:     John 2018-05-31 10:30:00 2018-05-31 11:00:00 2018-05-31 10:45:00
 3:     John 2018-05-31 10:30:00 2018-05-31 11:00:00 2018-05-31 11:00:00
 4:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00 2018-05-31 13:15:00
 5:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00 2018-05-31 13:30:00
 6:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00 2018-05-31 13:45:00
 7:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00 2018-05-31 14:00:00
 8:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00 2018-05-31 14:15:00
 9:     Paul 2018-05-31 12:30:00 2018-05-31 13:15:00 2018-05-31 12:30:00
10:     Paul 2018-05-31 12:30:00 2018-05-31 13:15:00 2018-05-31 12:45:00
11:     Paul 2018-05-31 12:30:00 2018-05-31 13:15:00 2018-05-31 13:00:00
12:     Paul 2018-05-31 12:30:00 2018-05-31 13:15:00 2018-05-31 13:15:00

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X