web-dev-qa-db-fra.com

Insérer des lignes pour les dates/heures manquantes

Je suis nouveau dans R, mais je me suis tourné vers lui pour résoudre un problème avec un ensemble de données volumineux que je tente de traiter. Actuellement, j'ai 4 colonnes de données (valeurs Y) définies par rapport à des horodatages d'intervalle minute (mois/jour/année heure: min) (valeurs X) comme ci-dessous:

    timestamp          tr            tt         sr         st  
1   9/1/01 0:00   1.018269e+02   -312.8622   -1959.393   4959.828  
2   9/1/01 0:01   1.023567e+02   -313.0002   -1957.755   4958.935  
3   9/1/01 0:02   1.018857e+02   -313.9406   -1956.799   4959.938  
4   9/1/01 0:03   1.025463e+02   -310.9261   -1957.347   4961.095  
5   9/1/01 0:04   1.010228e+02   -311.5469   -1957.786   4959.078

Le problème que j’ai, c’est que certaines valeurs d’horodatage manquent - par exemple. il peut y avoir un écart entre le 01/09/01 0:13 et le 01/09/01 0:27 et ces écarts sont irréguliers dans l'ensemble de données. Je dois mettre plusieurs de ces séries dans la même base de données et, comme les valeurs manquantes sont différentes pour chaque série, les dates ne sont pas alignées sur chaque ligne.

Je souhaite générer des lignes pour ces horodatages manquants et remplir les colonnes Y avec des valeurs vides (pas de données, pas de zéro), afin d'avoir une série chronologique continue.

Honnêtement, je ne sais pas trop par où commencer (je n’ai pas vraiment utilisé R avant d’apprendre au fur et à mesure de mon apprentissage!), Mais toute aide serait très appréciée. J’ai jusqu’à présent installé Chron et Zoo, car il me semble qu’ils pourraient être utiles.

Merci!

34
James A

Je pense que la chose la plus facile consiste à définir Date en premier comme décrit précédemment, à convertir en Zoo, puis à définir une fusion:

df$timestamp<-as.POSIXct(df$timestamp,format="%m/%d/%y %H:%M")

df1.Zoo<-Zoo(df[,-1],df[,1]) #set date to Index

df2 <- merge(df1.Zoo,zoo(,seq(start(df1.Zoo),end(df1.Zoo),by="min")), all=TRUE)

Le début et la fin sont donnés à partir de votre df1 (données d'origine) et vous réglez - par exemple, min - selon les besoins de votre exemple. all = TRUE définit toutes les valeurs manquantes aux dates manquantes sur NA.

23
Herr Student

C'est une vieille question, mais je voulais juste poster un moyen de gérer cela, car je suis tombé sur ce message tout en cherchant une réponse à un problème similaire. Je trouve cela plus intuitif et plus facile pour les yeux que l'approche du zoo.

library(dplyr)

ts <- seq.POSIXt(as.POSIXct("2001-09-01 0:00",'%m/%d/%y %H:%M'), as.POSIXct("2001-09-01 0:07",'%m/%d/%y %H:%M'), by="min")

ts <- seq.POSIXt(as.POSIXlt("2001-09-01 0:00"), as.POSIXlt("2001-09-01 0:07"), by="min")
ts <- format.POSIXct(ts,'%m/%d/%y %H:%M')

df <- data.frame(timestamp=ts)

data_with_missing_times <- full_join(df,original_data)

   timestamp     tr tt sr st
1 09/01/01 00:00 15 15 78 42
2 09/01/01 00:01 20 64 98 87
3 09/01/01 00:02 31 84 23 35
4 09/01/01 00:03 21 63 54 20
5 09/01/01 00:04 15 23 36 15
6 09/01/01 00:05 NA NA NA NA
7 09/01/01 00:06 NA NA NA NA
8 09/01/01 00:07 NA NA NA NA

En utilisant également dplyr, cela facilite la tâche, par exemple, de changer toutes ces valeurs manquantes en quelque chose d’autre, ce qui m’a été utile lors du traçage dans ggplot.

data_with_missing_times %>% group_by(timestamp) %>% mutate_each(funs(ifelse(is.na(.),0,.)))

   timestamp     tr tt sr st
1 09/01/01 00:00 15 15 78 42
2 09/01/01 00:01 20 64 98 87
3 09/01/01 00:02 31 84 23 35
4 09/01/01 00:03 21 63 54 20
5 09/01/01 00:04 15 23 36 15
6 09/01/01 00:05  0  0  0  0
7 09/01/01 00:06  0  0  0  0
8 09/01/01 00:07  0  0  0  0
29
lbollar

Le remplissage de la date est implémenté dans le package padr de R. Si vous stockez votre bloc de données, votre variable date-heure est stockée sous la forme POSIXct ou POSIXlt. Tout ce que vous devez faire c'est:

library(padr)
pad(df_name)

Voir vignette ("padr") ou cet article de blog pour son fonctionnement.

13
Edwin
# some made-up data
originaldf <- data.frame(timestamp=c("9/1/01 0:00","9/1/01 0:01","9/1/01 0:03","9/1/01 0:04"),
    tr = rnorm(4,0,1),
    tt = rnorm(4,0,1))

originaldf$minAsPOSIX <- as.POSIXct(originaldf$timestamp, format="%m/%d/%y %H:%M", tz="GMT")

# Generate vector of all minutes
ndays <- 1 # number of days to generate
minAsNumeric <- 60*60*24*243 + seq(0,60*60*24*ndays,by=60)

# convert those minutes to POSIX
minAsPOSIX <- as.POSIXct(minAsNumeric, Origin="2001-01-01", tz="GMT")

# new df
newdf <- merge(data.frame(minAsPOSIX),originaldf,all.x=TRUE, by="minAsPOSIX")
2
Thomas

Si vous souhaitez remplacer les valeurs NA acquises par l'une des méthodes mentionnées ci-dessus par des zéros, procédez comme suit:

df[is.na(df)] <- 0

(Je voulais à l'origine commenter ceci sur la réponse d'Ibollar, mais je manque de la réputation nécessaire, c'est pourquoi j'ai posté comme réponse)

1
s-heins
df1.Zoo <- Zoo(df1[,-1], as.POSIXlt(df1[,1], format = "%Y-%m-%d %H:%M:%S")) #set date to Index: Notice that column 1 is Timestamp type and is named as "TS"

full.frame.Zoo <- Zoo(NA, seq(start(df1.Zoo), end(df1.Zoo), by="min")) # Zoo object
full.frame.df  <- data.frame(TS = as.POSIXlt(index(full.frame.Zoo), format = "%Y-%m-%d %H:%M:%S")) # conver Zoo object to data frame

full.vancouver <- merge(full.frame.df, df1, all = TRUE) # merge
0
Rotail

Je cherchais quelque chose de similaire: au lieu de remplir les horodatages manquants, mes données étaient en mois et en jours. Je voulais donc générer une séquence de mois qui tienne compte des années bissextiles, etc. J'ai utilisé lubridate:

date <- df$timestamp[1]
date_list <- c(date)
while (date < df$timestamp[nrow(df)]){
    date <- date %m+% months(1) 
    date_list <- c(date_list,date)
}
date_list <- format(as.Date(date_list),"%Y-%m-%d")
df_1 <- data.frame(months=date_list, stringsAsFactors = F)

Cela me donnera une liste de dates par mois. Puis je rejoins

df_with_missing_months <- full_join(df_1,df)
0
Kevin Ogoro