【问题标题】:R Issue adding NA values for missing rows using data framesR问题使用数据框为丢失的行添加NA值
【发布时间】:2016-02-02 21:31:45
【问题描述】:

提前感谢您提供的任何帮助。

长话短说:我正在处理来自测量设备的每小时时间序列数据(从 SQL 导出,然后导入到 R 以正确格式化日期时间) - 时间序列包含缺失数据,有时是分组数据,并且我需要找到这些缺失的行/索引,并为每个包含 NA 值的实例插入一个新行。

没有解决我的问题的相关问题:

how to insert missing observations on a data frame

Adding row to a data frame with missing values

问题数据

在这种情况下,我使用的数据集相当大,并且取决于我选择的测量设备。作为一个测试用例,我有一个包含 17469 小时观测值的时间序列。我找到了可用于测试目的的一小部分数据集。这里是:

> snip
                   date Reading
408 2015-12-15 00:00:00    4.40
409 2015-12-14 23:00:00    4.62
410 2015-12-14 22:00:00    4.61
411 2015-12-14 21:00:00    6.15
412 2015-12-14 20:00:00    6.06
413 2015-12-14 19:00:00    7.04
414 2015-12-14 18:00:00    8.57
415 2015-12-14 11:00:00    4.12
416 2015-12-14 10:00:00    3.73

我们可以看到 2015-12-14 12:00:00 到 2015-12-14 17:00:00 的观测值缺失。我想先定位然后用这些日期时间填充时间序列,并在这些位置为阅读列输入NA。我还想返回附加向量中缺少的索引。

如何做到这一点?

到目前为止,我已经尝试了以下代码(如此处所建议,how to add a missing dates and remove repeated dates in hourly time series),但当我执行merge 函数时,我最终得到的只是NA 值,并且仍然需要确定缺少的索引在哪里位于。

结果如下:

> grid = data.frame(date=seq.POSIXt(min(snip[,1]), to=max(snip[,1]), by="1 hours"));
> dat = merge(grid, snip, by="date", all.x=TRUE)
> dat
                  date Reading
1  2015-12-14 10:00:00      NA
2  2015-12-14 11:00:00      NA
3  2015-12-14 12:00:00      NA
4  2015-12-14 13:00:00      NA
5  2015-12-14 14:00:00      NA
6  2015-12-14 15:00:00      NA
7  2015-12-14 16:00:00      NA
8  2015-12-14 17:00:00      NA
9  2015-12-14 18:00:00      NA
10 2015-12-14 19:00:00      NA
11 2015-12-14 20:00:00      NA
12 2015-12-14 21:00:00      NA
13 2015-12-14 22:00:00      NA
14 2015-12-14 23:00:00      NA
15 2015-12-15 00:00:00      NA

我在这里缺少什么?是因为gridsnip$date 顺序相反吗?有关其他信息,这里是日期时间格式的样子(如果这是我的问题的根源):

> snip[2,1]
[1] "2015-12-14 23:00:00 GMT"

dput(snip)命令的结果如下(感谢@42的建议):

> dput(snip)
structure(list(date = structure(list(sec = c(0, 0, 0, 0, 0, 0, 
0, 0, 0), min = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), hour = c(0L, 
23L, 22L, 21L, 20L, 19L, 18L, 11L, 10L), mday = c(15L, 14L, 14L, 
14L, 14L, 14L, 14L, 14L, 14L), mon = c(11L, 11L, 11L, 11L, 11L, 
11L, 11L, 11L, 11L), year = c(115L, 115L, 115L, 115L, 115L, 115L, 
115L, 115L, 115L), wday = c(2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L
), yday = c(348L, 347L, 347L, 347L, 347L, 347L, 347L, 347L, 347L
), isdst = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), .Names = c("sec", 
"min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"
), class = c("POSIXlt", "POSIXt"), tzone = "GMT"), Reading = c(4.4, 
4.62, 4.61, 6.15, 6.06, 7.04, 8.57, 4.12, 3.73)), .Names = c("date", 
"Reading"), row.names = 408:416, class = "data.frame")

【问题讨论】:

  • POSIXct 值是数字,无法通过打印方法完全显示。我们需要查看dput(snip) 才能知道实际的潜在价值是什么。您可以合并它们的格式化(文本)值

标签: r datetime dataframe missing-data


【解决方案1】:

在 na.locf 文档的帮助下,我是如何做到这一点的。它有帮助吗?

dat<- dget("yoursample")
require(xts)
datxts<- as.xts(dat[,-1],order.by = dat$date,frequency = 24)
tzn<-tzone(datxts)
g<- seq(start(datxts), end(datxts), "hour")
gxts<- xts(rep(NA,length(g)),order.by = as.POSIXct(g), tzone = tzn)

merge(datxts,gxts,all = T)$datxts

编辑:此外,如果您将一列 NA 添加到生成的数据帧中,您的方法也有效

dates=seq.POSIXt(min(snip[,1]), to=max(snip[,1]), by="1 hours")
grid = data.frame(date=dates,dummydata=rep(NA,length(dates)));
dat = merge(grid, snip, by="date", all=T)

【讨论】:

  • 漂亮,您的第一个解决方案效果很好。但是,第二种解决方案只是为原始列表中的每个日期时间附加一个 NA 值,同时将 NA 放在缺失的行中,它还填充一个 NA 以获取可用的观察结果。
  • 有没有一种简单的方法来创建缺失观测值的向量,可能是通过对 datxtsgxts 中包含的日期进行设置差异(抱歉,我主要在 MATLAB 中工作)?
  • 第二个中的 dat$reading 列应该与第一个答案相同。您是否收到有关时区不匹配的警告?第二个问题——您只需要缺少数据的日期,对吗?
  • 抱歉,剩下的就在这里,以获取丢失的时间:as.POSIXct(setdiff(g, dat$date), origin="1970-01-01", tz="GMT") ..不过可能有更短的方法..
  • 第一条评论:我没有收到任何错误,dat 变成了一个 25x3 的数据框,在 $Reading 列中附加了 NA 以表示缺少的日期以及那些日期观察已经存在。它应该是 15x3,NA 只出现在那些缺少观察的日期
猜你喜欢
  • 2011-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
相关资源
最近更新 更多