1
votes

Modifier les temps manquants dans la série datetime dans R

J'ai une série temporelle horaire de datetimes formatée comme "% Y-% m-% d% H:% M:% S" et comme classe "caractère". Le but est de convertir les données de caractères en date et heure en utilisant as.POSIXct. Cependant, certains enregistrements de la série chronologique n'ont pas la partie temporelle ("% H:% M:% S"), bien que le nombre d'enregistrements par date (24) soit correct.

Est-il possible de renseigner l'heure partie de ces enregistrements avec une séquence d'heures commençant par 00:00:00 et se terminant par 23:00:00 pour chaque date?

Ensemble de données d'origine:

 X metadata.id metadata.name metadata.lat metadata.lon              Date_time data.v data.s data.f
1   1     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 01:00:00     NA     NA    1,1
2   2     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 02:00:00     NA     NA    1,1
3   3     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 03:00:00     NA     NA    1,1
4   4     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 04:00:00     NA     NA    1,1
5   5     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 05:00:00     NA     NA    1,1
6   6     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 06:00:00     NA     NA    1,1
7   7     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 07:00:00     NA     NA    1,1
8   8     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 08:00:00     NA     NA    1,1
9   9     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 09:00:00     NA     NA    1,1
10 10     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 10:00:00     NA     NA    1,1
11 11     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 11:00:00     NA     NA    1,1
12 12     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 12:00:00     NA     NA    1,1
13 13     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 13:00:00     NA     NA    1,1
14 14     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 14:00:00     NA     NA    1,1
15 15     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 15:00:00     NA     NA    1,1
16 16     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 16:00:00     NA     NA    1,1
17 17     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 17:00:00     NA     NA    1,1
18 18     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 18:00:00     NA     NA    1,1
19 19     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 19:00:00     NA     NA    1,1
20 20     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 20:00:00     NA     NA    1,1
21 21     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 21:00:00     NA     NA    1,1
22 22     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 22:00:00     NA     NA    1,1
23 23     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 23:00:00     NA     NA    1,1
24 24     9411340 Santa Barbara      34.4031    -119.6928 1990-10-23 00:00:00     NA     NA    1,1
25 25     9411340 Santa Barbara      34.4031    -119.6928 1990-10-23 01:00:00     NA     NA    1,1

Ce que je veux:

Date_time 
...
1991-03-31 21:00:00
1991-03-31 22:00:00 
1991-03-31 23:00:00
1991-04-01 16:00:00
1991-04-01 17:00:00
1991-04-01 18:00:00
...

Le plus proche que j'ai obtenu est une solution de contournement tout en étant toujours au format caractère, mais le résultat commence à 16:00:00. Veuillez envoyer halp.

hours=c("00:00:00", "01:00:00", "02:00:00", "03:00:00", "04:00:00", "05:00:00", "06:00:00", "07:00:00", "08:00:00", "09:00:00", "10:00:00", "11:00:00", "12:00:00","13:00:00", "14:00:00", "15:00:00", "16:00:00", "17:00:00", "18:00:00", "19:00:00", "20:00:00","21:00:00", "22:00:00", "23:00:00")

Dataset %>%
  mutate(Date_time_filled = ifelse(nchar(as.character(Date_time))<19, 
                                   paste(Date_time, hours), 
                                   paste(Date_time)))

Ce que j'ai (mal):

Date_time 
...
1991-03-31 21:00:00
1991-03-31 22:00:00 
1991-03-31 23:00:00
1991-04-01 00:00:00
1991-04-01 01:00:00
1991-04-01 02:00:00
...

MODIFIER:

Date_time 
...
1991-03-31 21:00:00
1991-03-31 22:00:00 
1991-03-31 23:00:00
1991-04-01
1991-04-01
1991-04-01
...


0 commentaires

3 Réponses :


1
votes

Je ne sais pas si c'est ce que vous recherchez, ou du moins cela peut vous mettre sur la bonne voie:

Dataset$date_time_filled <- seq(as.POSIXct(Dataset$date_time[1]),
                                as.POSIXct(Dataset$date_time[nrow(Dataset)]), 
                                by = "1 hour")

Cela pourrait être utilisé comme ceci:

# This is the working horse:
seq(as.POSIXct("1991-03-31 00:00:00"), as.POSIXct("1991-04-02 23:00:00"), by = "1 hour")

 [1] "1991-03-31 00:00:00 -05" "1991-03-31 01:00:00 -05" "1991-03-31 02:00:00 -05" "1991-03-31 03:00:00 -05" "1991-03-31 04:00:00 -05"
 [6] "1991-03-31 05:00:00 -05" "1991-03-31 06:00:00 -05" "1991-03-31 07:00:00 -05" "1991-03-31 08:00:00 -05" "1991-03-31 09:00:00 -05"
[11] "1991-03-31 10:00:00 -05" "1991-03-31 11:00:00 -05" "1991-03-31 12:00:00 -05" "1991-03-31 13:00:00 -05" "1991-03-31 14:00:00 -05"
[16] "1991-03-31 15:00:00 -05" "1991-03-31 16:00:00 -05" "1991-03-31 17:00:00 -05" "1991-03-31 18:00:00 -05" "1991-03-31 19:00:00 -05"
[21] "1991-03-31 20:00:00 -05" "1991-03-31 21:00:00 -05" "1991-03-31 22:00:00 -05" "1991-03-31 23:00:00 -05" "1991-04-01 00:00:00 -05"
[26] "1991-04-01 01:00:00 -05" "1991-04-01 02:00:00 -05" "1991-04-01 03:00:00 -05" "1991-04-01 04:00:00 -05" "1991-04-01 05:00:00 -05"
[31] "1991-04-01 06:00:00 -05" "1991-04-01 07:00:00 -05" "1991-04-01 08:00:00 -05" "1991-04-01 09:00:00 -05" "1991-04-01 10:00:00 -05"
[36] "1991-04-01 11:00:00 -05" "1991-04-01 12:00:00 -05" "1991-04-01 13:00:00 -05" "1991-04-01 14:00:00 -05" "1991-04-01 15:00:00 -05"
[41] "1991-04-01 16:00:00 -05" "1991-04-01 17:00:00 -05" "1991-04-01 18:00:00 -05" "1991-04-01 19:00:00 -05" "1991-04-01 20:00:00 -05"
[46] "1991-04-01 21:00:00 -05" "1991-04-01 22:00:00 -05" "1991-04-01 23:00:00 -05" "1991-04-02 00:00:00 -05" "1991-04-02 01:00:00 -05"
[51] "1991-04-02 02:00:00 -05" "1991-04-02 03:00:00 -05" "1991-04-02 04:00:00 -05" "1991-04-02 05:00:00 -05" "1991-04-02 06:00:00 -05"
[56] "1991-04-02 07:00:00 -05" "1991-04-02 08:00:00 -05" "1991-04-02 09:00:00 -05" "1991-04-02 10:00:00 -05" "1991-04-02 11:00:00 -05"
[61] "1991-04-02 12:00:00 -05" "1991-04-02 13:00:00 -05" "1991-04-02 14:00:00 -05" "1991-04-02 15:00:00 -05" "1991-04-02 16:00:00 -05"
[66] "1991-04-02 17:00:00 -05" "1991-04-02 18:00:00 -05" "1991-04-02 19:00:00 -05" "1991-04-02 20:00:00 -05" "1991-04-02 21:00:00 -05"
[71] "1991-04-02 22:00:00 -05" "1991-04-02 23:00:00 -05"

Dans le cas où la dernière lecture de date_time manque l'heure, cela fonctionnera, mais considérera la dernière comme si elle avait eu lieu à 00:00:00, donc il peut se tromper en raison de longueurs de vecteur différentes. Que vous devrez probablement ajuster manuellement.


1 commentaires

Merci pour ce @PavoDive. Je pense que j'avais des longueurs de vecteur différentes qui compliquaient les choses. Voir ma réponse ci-dessous. Merci encore.



0
votes

Comme vous avez déjà un certain nombre d'enregistrements présents pour chaque date et que seule la partie heure manque, une approche consiste à utiliser sprintf et à reproduire la partie heure pour chaque date.

df <- structure(list(Date_time = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 
7L, 7L, 7L, 7L, 7L, 7L), .Label = c("1991-03-31 00:00:00", "1991-03-31 01:00:00", 
"1991-03-31 02:00:00", "1991-03-31 03:00:00", "1991-03-31 04:00:00", 
"1991-03-31 05:00:00", "1991-04-01"), class = "factor")), class = 
"data.frame", row.names = c(NA, -12L))

Essayez ceci pendant les heures 0 à 5 sur un petit sous-ensemble.

library(dplyr)
df %>%
  mutate(Date_time1 = as.POSIXct(Date_time), 
         Date_time1 = paste(Date_time1, sprintf("%02d:00:00", 0:5)))


#             Date_time          Date_time1
#1  1991-03-31 00:00:00 1991-03-31 00:00:00
#2  1991-03-31 01:00:00 1991-03-31 01:00:00
#3  1991-03-31 02:00:00 1991-03-31 02:00:00
#4  1991-03-31 03:00:00 1991-03-31 03:00:00
#5  1991-03-31 04:00:00 1991-03-31 04:00:00
#6  1991-03-31 05:00:00 1991-03-31 05:00:00
#7           1991-04-01 1991-04-01 00:00:00
#8           1991-04-01 1991-04-01 01:00:00
#9           1991-04-01 1991-04-01 02:00:00
#10          1991-04-01 1991-04-01 03:00:00
#11          1991-04-01 1991-04-01 04:00:00
#12          1991-04-01 1991-04-01 05:00:00

Vous pouvez exécuter as.POSIXct sur la colonne Date_time1 pour le convertir en POSIXct objet.

données

library(dplyr)

df %>%
  mutate(Date_time1 = as.POSIXct(Date_time), 
         Date_time1 = paste(Date_time1, sprintf("%02d:00:00", 0:23)))


5 commentaires

J'aime beaucoup cette solution, mais pour une raison quelconque, le premier temps rempli commence toujours à 16:00:00 et non à 00:00:00 lorsque j'essaye de postuler à mes données. Cependant, vos données d'exemple fonctionnent très bien.


@dough Pouvez-vous mettre à jour votre message avec les premières lignes de vos données comme je l'ai fait avec dput ? Faites dput (head (df, 25)) et copiez / collez la sortie dans votre message.


Il en résulte probablement 16h00 au lieu de 00h00 en raison du fuseau horaire dans lequel vous vous trouvez. Utilisez l'argument tz = dans l'appel à as.POSIXct . Voir aussi sa page d'aide


@RonakShah J'ai ajouté les premières lignes de mes données réelles.


@PavoDive non, y compris le fuseau horaire, n'a pas aidé. J'ai utilisé Date_time = as.POSIXct ((Date_time), origin = "1970-01-01", tz = "America / Los_Angeles", format = "% Y-% m-% d% H:% M:% S" ). Cependant, je voulais éviter de mettre les données au format date-heure pour l'instant, car cela semble compliquer les choses



0
votes

Au lieu d'ajouter les temps manquants dans l'ensemble de données de la série chronologique, j'ai fini par devoir revenir aux ensembles de données individuels ne contenant qu'un mois de données. Les mois de données manquantes étaient toujours avril, donc 30 jours. Ensuite, ce qui suit a fonctionné:

#Fix April Datasets missing hour data
hours=c("00:00:00", "01:00:00", "02:00:00", "03:00:00", "04:00:00", "05:00:00", "06:00:00", "07:00:00", "08:00:00", "09:00:00", "10:00:00", "11:00:00", "12:00:00","13:00:00", "14:00:00", "15:00:00", "16:00:00", "17:00:00", "18:00:00", "19:00:00", "20:00:00","21:00:00", "22:00:00", "23:00:00")
pattern=glob2rx("******04**.csv")

#Monthly Dataset
MonthlyData_filenames=list.files(path="~/.../Hourly",
                        pattern=pattern, full.names = T)
for(i in 1:length(MonthlyData_filenames)){
  input = read.csv(MonthlyData_filenames[i], head=TRUE, sep=",")
  if(nchar(as.character(input$Date_time))>=19){
    next
  }
  output = input %>%
    mutate(hour = rep(hours, times=30)) %>%
    mutate(Date_time = paste(Date_time, hour, sep=" ")) %>%
    select(-hour)
  write.csv(output, MonthlyData_filenames[i], row.names=FALSE)
}


0 commentaires