Wstaw wiersze dla brakujących dat/godzin

Jestem nowy w R, ale zwróciłem się do niego, aby rozwiązać problem z dużym zestawem danych, które próbuję przetworzyć. Obecnie mam 4 kolumny danych (wartości Y) ustawione na znaczniki czasu interwału minutowego (miesiąc / dzień/rok godzina: min) (wartości X) jak poniżej:

    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

Mój problem polega na tym, że brakuje pewnych wartości znaczników czasu - np. może istnieć luka między 9/1/01 0:13 a 9/1/01 0:27 i takie luki są nieregularne w zestawie danych. Muszę umieścić kilka z tych serii w tej samej bazie danych a ponieważ brakujące wartości są różne dla każdej serii, daty nie są obecnie wyrównywane w każdym wierszu.

Chciałbym wygenerować wiersze dla tych brakujących znaczników czasu i wypełnić kolumny Y pustymi wartościami( brak danych, nie zero), tak aby mieć ciągły szereg czasowy.

Szczerze mówiąc nie jestem do końca pewien, od czego zacząć (wcześniej nie używałem R, więc uczę się jak idę!), ale każda pomoc byłaby mile widziana. Do tej pory zainstalowałem chron i zoo, ponieważ wydaje się, że mogą być przydatne.

Dzięki!
Author: Jaap, 2013-05-28

7 answers

Myślę, że najprostszą rzeczą jest najpierw ustawić datę, jak już opisano, przekonwertować do zoo, a następnie po prostu ustawić merge:

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)

Początek i koniec są podane z twojego df1 (oryginalnych danych) i ustawiasz przez-np. min-tak jak potrzebujesz dla Twojego przykładu. all = TRUE ustawia na serwerze NAs wszystkie brakujące wartości w brakujących datach.

 21
Author: Herr Student,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-28 12:07:19

To stare pytanie, ale po prostu chciałem opublikować sposób obsługi dplyr, ponieważ natknąłem się na ten post, szukając odpowiedzi na podobny problem. Uważam, że jest to bardziej intuicyjne i łatwiejsze dla oczu niż podejście do 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

Również przy użyciu dplyr, ułatwia to coś takiego jak zmiana wszystkich brakujących wartości na coś innego, co przydało mi się podczas wykreślania w 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
 27
Author: lbollar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-17 20:53:53

Date padding jest zaimplementowany w pakiecie padr w R. jeśli przechowujesz ramkę danych, ze zmienną date-time przechowywaną jako POSIXct lub POSIXlt. Wszystko co musisz zrobić to:

library(padr)
pad(df_name)

Zobacz winietę ("padr") lub ten wpis na blogu, aby jej użyć.

 10
Author: Edwin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-20 15:41:39
# 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
Author: Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-28 11:20:48

W przypadku, gdy chcesz zastąpić wartości NA uzyskane za pomocą dowolnej metody wymienionej powyżej zerami, możesz to zrobić:

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

(orginalnie chciałem skomentować to w odpowiedzi Ibollar, ale brakuje mi niezbędnej reputacji, dlatego zamieściłem jako odpowiedź)

 1
Author: s-heins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-16 17:32:03
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
Author: Rotail,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-07 21:45:09

Szukałem czegoś podobnego, gdzie zamiast wypełniać brakujące znaczniki czasu moje dane były w miesiącach i dniach. Więc chciałem wygenerować sekwencję miesięcy, które zaspokoiłyby lata przestępne i tak dalej. Użyłem 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)

To da mi listę dat w kolejnych miesiącach. Wtedy dołączam się

df_with_missing_months <- full_join(df_1,df)
 0
Author: Kevin Ogoro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-19 06:56:47