56

我是 R 新手,但已经转向它来解决我正在尝试处理的大型数据集的问题。目前,我针对分钟间隔时间戳(月/日/年小时:分钟)(X 值)设置了 4 列数据(Y 值),如下所示:

    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

我遇到的问题是缺少一些时间戳值 - 例如,9/1/01 0:13 和 9/1/01 0:27 之间可能存在间隙,并且此类间隙在数据集中是不规则的。我需要将这些系列中的几个放入同一个数据库中,并且由于每个系列的缺失值不同,因此日期当前并未在每一行上对齐。

我想为这些缺失的时间戳生成行,并用空白值(没有数据,不是零)填充 Y 列,这样我就有了一个连续的时间序列。

老实说,我不太确定从哪里开始(在我继续学习之前并没有真正使用过 R!)但任何帮助将不胜感激。到目前为止,我已经安装了 chron 和 zoo,因为它们似乎很有用。

谢谢!

4

9 回答 9

46

这是一个老问题,但我只是想发布一个处理这个问题的 dplyr 方法,因为我在寻找类似问题的答案时遇到了这篇文章。我发现它比动物园方法更直观,更容易。

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

同样使用 dplyr,这使得做一些事情变得更容易,比如将所有缺失的值更改为其他值,这在 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
于 2015-07-17T20:53:53.300 回答
28

我认为最简单的方法是先设置日期,如前所述,转换为动物园,然后设置合并:

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)

开始和结束是从您的 df1 (原始数据)给出的,并且您正在设置 - 例如 min - 根据您的示例需要。all=TRUE 将缺失日期的所有缺失值设置为 NA。

于 2013-05-28T12:07:19.733 回答
28

日期填充padr在 R 的包中实现。如果您存储数据框,则日期时间变量存储为POSIXctor POSIXlt。您需要做的就是:

library(padr)
pad(df_name)

请参阅 vignette("padr") 或此博客文章了解其工作原理。

于 2017-01-20T15:41:39.477 回答
16

我认为这可以通过使用completein tidyrpackage 来完成。

library(tidyverse)
df <- df %>%
      complete(timestamp = seq.POSIXt(min(timestamp), max(timestamp), by = "minute"), 
               tr, tt, sr,st)

您还可以初始化您的开始日期和结束日期,而不是使用min(timestamp)and max(timestamp)

于 2019-04-26T19:34:16.437 回答
2
# 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")
于 2013-05-28T11:20:48.553 回答
0
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
于 2016-09-07T21:45:09.963 回答
0

如果您想用零替换上述任何方法获取的 NA 值,您可以这样做:

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

(我原本想对 Ibollar 的回答发表评论,但我缺乏必要的声誉,因此我将其发布为答案)

于 2016-02-16T17:32:03.437 回答
0

在 R 中处理时间序列数据有一些进步,例如,tsibble 以整洁的方式添加了这样的时间序列操作:

library(tsibble)
library(lubridate)

ts <- lubridate::dmy_hm(c("9/1/01 0:00","9/1/01 0:01","9/1/01 0:03","9/1/01 0:27"))
originaldf <- tsibble(timestamp = ts,
                      tr        = rnorm(4,0,1),
                      tt        = rnorm(4,0,1),
                      index     = timestamp)

originaldf %>% 
  fill_gaps()
于 2019-03-26T09:23:51.530 回答
-1

我正在寻找类似的东西,而不是填写丢失的时间戳,我的数据是几个月和几天。所以我想生成一个月份序列来满足闰年等等。我用过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)

这会给我一个增量月份的日期列表。然后我加入

df_with_missing_months <- full_join(df_1,df)
于 2017-05-19T06:56:47.720 回答