【问题标题】:Aggregate 5 minute data to hourly sums with NA's使用 NA 将 5 分钟数据汇总为每小时总和
【发布时间】:2015-11-20 13:28:55
【问题描述】:

我的问题如下:我有一个包含 5 分钟降水数据的时间序列,例如:

            Datum mm
1 2004-04-08 00:05:00 NA
2 2004-04-08 00:10:00 NA
3 2004-04-08 00:15:00 NA
4 2004-04-08 00:20:00 NA
5 2004-04-08 00:25:00 NA
6 2004-04-08 00:30:00 NA

采用这种结构:

'data.frame':   1098144 obs. of  2 variables:
$ Datum: POSIXlt, format: "2004-04-08 00:05:00" "2004-04-08 00:10:00"   "2004-04-08 00:15:00" "2004-04-08 00:20:00" ...
$ mm   : num  NA NA NA NA NA NA NA NA NA NA ...

如您所见,时间序列以大量NA's 开头,但在更下方有测量的降水,尽管由于测量站故障而充斥着单一的、不太常见的NA's

我想要实现的是将测得的降水量总结为每小时总和,而不考虑 NA's

这是我迄今为止尝试过的:

sums <- aggregate(precip["mm"], 
               list(cut(precip$Datum, "1 hour")), sum)

即使时间戳正确聚合到小时,所有总和都是0NA。如果根本没有NA,则甚至不会计算总和。

另外需要考虑:

气象学中每小时降水量总和总是描述直到某个小时的累积总和:0:00点的降水量描述从前一天23:00到的总和 0:00。所以我总是需要总结前一个小时。

可重现的示例

set.seed(1120)
s <- as.POSIXlt("2004-03-08 23:00:00")
r <- seq(s, s+1e4, "30 min")
precip <- data.frame(Datum=r, mm=sample(c(1:5,NA), 6, T))

            Datum mm
2004-03-08 23:00:00  4
2004-03-08 23:30:00  1
2004-03-09 00:00:00  2
2004-03-09 00:30:00  4
2004-03-09 01:00:00  1
2004-03-09 01:30:00  4

通过上面的例子,我正在寻找的结果是:

            Datum mm
2004-03-09 00:00:00 5
2004-03-09 01:00:00 6
2004-03-09 02:00:00 5

【问题讨论】:

  • 未来,请考虑阅读How to Ask 以及如何创建reproducible example in R。如果您提供明确的预期输出,则其他人可以更轻松地为您提供帮助,而无需大量澄清。
  • 在示例数据框中,输出应该是什么?请回答实际代码而不是输出的书面描述。
  • 我们真的来回走了这么久,而您一直都有解决方案吗?我最初的解决方案会产生该输出。
  • 不,抱歉,它没有。在我想要的结果中,2004-03-09 00:00:00 (= 5) 的总和是 23:00 和 23:30 的 4+1 之和。它被转移了。

标签: r time-series aggregate


【解决方案1】:

尝试添加na.rm=TRUE:

aggregate(precip['mm'], list(cut(precip$Datum, "1 hour")), sum, na.rm=TRUE)
#               Group.1 mm
# 1 2004-04-08 00:00:00 26
# 2 2004-04-08 01:00:00 35
# 3 2004-04-08 02:00:00 25

可重现的示例

set.seed(1120)
s <- as.POSIXlt("2004-04-08 00:05:00")
r <- seq(s, s+1e4, "5 min")
precip <- data.frame(Datum=r, mm=sample(c(1:5,NA), 34, T))

附录

关于您的第二个问题:如果您想用较小的小时计算小时的测量值,请添加right=TRUE

aggregate(precip['mm'], list(cut(precip$Datum, "1 hour", right=TRUE)), sum, na.rm=TRUE)

进一步说明

我们将创建另一个更详细的解释来展示解决方案的工作原理:

p <- c("2004-04-07 23:48:20", "2004-04-08 00:00:00", "2004-04-08 00:03:20")
ptime <- as.POSIXlt(p)
#[1] "2004-04-07 23:48:20 EDT" "2004-04-08 00:00:00 EDT" "2004-04-08 00:03:20 EDT"

我们有三个日期可以分组。如果我们使用 cut 而不使用任何额外参数,则第二个条目 "2004-04-08 00:00:00 EDT" 将与第三个条目分组为小时 "00:00"

cut(ptime, "1 hour")
#[1] 2004-04-07 23:00:00 2004-04-08 00:00:00 2004-04-08 00:00:00

但如果我们添加参数right=FALSE,我们可以将其与"23:00" 小时分组:

cut(ptime, "1 hour", right=TRUE)
#[1] 2004-04-07 23:00:00 2004-04-07 23:00:00 2004-04-08 00:00:00

我们可以指定边缘情况的行为。

编辑

使用您的新数据,原始解决方案会产生所需的输出:

aggregate(precip['mm'], list(cut(precip$Datum, "1 hour")), sum, na.rm=TRUE)
              Group.1 mm
1 2004-03-08 23:00:00  5
2 2004-03-09 00:00:00  6
3 2004-03-09 01:00:00  5

【讨论】:

  • 您的解决方案已成功删除所有 NA's,但仍然没有计算总和,每小时总和为 0
  • 您是否尝试过可重现的示例?如果您的数据不同,请注明出处。
  • 好的,非常感谢!感谢您的示例,我意识到降水列未正确加载为数字变量,因为十进制分隔符是 ,...德国人...!
  • 很抱歉再次打扰您,但现在 - 要正确执行 - 例如的总和18:00是18:00-19:00的总和,其实应该是17:00-18:00的总和。
  • 您的预期输出不清楚。就像我们对第一个问题所做的那样,我想强调创建示例的重要性。如果您使用所需的输出创建一个小示例,那么提供帮助会容易得多。我想你现在知道我在真诚地试图帮助你。请通过在您的原始帖子中添加一个具体示例来帮助我。
【解决方案2】:

您可以使用 dplyr 来计算总和,例如:

precip$hour <-  strftime(precip$Datum,"%Y-%m-%d %H")
library(dplyr)
sum_hour <- precip %>% group_by(hour) %>% summarise(sum_hour = sum(mm,na.rm = T))

【讨论】:

  • 感谢您的回答,但它也不考虑我对@PierreLafortune 回答的最后评论。期待您的解决方案!
  • 你的意思是如果小时是 4:00,它应该计算为 (3:00 到 4:00) 吗?如果是,你会在 0:00 时做什么?
  • 是的,4:00 的总和应该是 3:00-4:00,0:00 的总和应该是 23:00-0:00 的总和......现在这个很棘手。
  • 前一天23:00?
猜你喜欢
  • 1970-01-01
  • 2016-08-27
  • 2011-07-09
  • 2018-04-23
  • 2019-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-10
相关资源
最近更新 更多