Insérer des lignes pour les dates/heures manquantes
Je suis nouveau sur R mais je me suis tourné vers lui pour résoudre un problème avec un grand ensemble de données que j'essaie de traiter. Actuellement, j'ai 4 colonnes de données (valeurs Y) définies par rapport aux horodatages d'intervalle des minutes (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 est que certaines valeurs d'horodatage sont manquantes - par exemple, il peut y avoir un écart entre 9/1/01 0:13 et 9/1/01 0:27 et de tels écarts sont irréguliers à travers l'ensemble de données. J'ai besoin de 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 s'alignent pas actuellement sur chaque ligne.
Je voudrais 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), de sorte que j'ai une série temporelle continue.
Honnêtement, je ne suis pas tout à fait sûr par où commencer (pas vraiment utilisé R avant d'apprendre au fur et à mesure!), mais toute aide serait grandement appréciée. J'ai donc installé chron et zoo, car il semble qu'ils pourraient être utile.
Merci!
7 réponses
Je pense que la chose la plus simple est de définir la Date d'abord comme déjà décrit, de convertir en zoo, puis de 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)
Start et end sont donnés à partir de votre df1 (données d'origine) et vous définissez par - par exemple min - comme vous le souhaitez pour votre exemple. all = TRUE définit toutes les valeurs manquantes aux dates manquantes sur NAs.
C'est une vieille question, mais je voulais juste poster un dplyr cela, que je suis tombé sur ce post en cherchant une réponse à un problème similaire. Je trouve cela plus intuitif et plus facile sur 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, il est plus facile de faire quelque chose comme changer toutes ces valeurs manquantes en autre chose, ce qui m'est 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
Date padding est implémenté dans le package padr
dans R. Si vous stockez votre trame de données, avec votre variable date-heure stockée comme POSIXct
ou POSIXlt
. Tout ce que vous devez faire est:
library(padr)
pad(df_name)
Voir vignette ("padr") ou ce billet de blog pour son fonctionnement.
# 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")
Si vous voulez remplacer les valeurs NA acquises par une méthode mentionnée ci-dessus par des zéros, vous pouvez le faire:
df[is.na(df)] <- 0
(je voulais initialement commenter ceci sur la réponse D'Ibollar mais je manque de la réputation nécessaire, donc j'ai posté comme réponse)
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
Je cherchais quelque chose de similaire où au lieu de remplir les horodatages manquants mes données étaient en mois et en jours. Donc, je voulais générer une séquence de mois qui répondrait aux années bissextiles et cetera. 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 en mois incrémentiels. Ensuite, je rejoins
df_with_missing_months <- full_join(df_1,df)