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!
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.
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
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.
# 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 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)
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: 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)