【问题标题】:Minimum of moving windows based on hours in RR中基于小时的移动窗口的最小值
【发布时间】:2021-05-04 10:24:58
【问题描述】:

我有一个数据框,其中第一列是日期,第三列是数据。像这样:

我必须创建移动窗口,从 1:30:00 到 2:30:00 和 2:30:00-3:30:00 等。 我必须在所有窗口中搜索第三列的每个最小值。我发现了这个 runmin() 东西,但它并没有真正起作用,也不明白它是如何工作的

样本数据:

# build data programmatically
dat <- data.frame(
  timestamp = as.POSIXct("2020-01-19 01:30:00", tz = "UTC") + seq(0, 3600, by=600),
  int = 1L,
  val = c(25, 70, 68, 53, 63, 65, 52)
)
# dump of existing data, e.g., dput(head(dat, 6))
dat <- structure(list(timestamp = structure(c(1579397400, 1579398000, 1579398600, 1579399200, 1579399800, 1579400400, 1579401000), class = c("POSIXct", "POSIXt"), tzone = "UTC"), int = c(1L, 1L, 1L, 1L, 1L, 1L, 1L), val = c(25, 70, 68, 53, 63, 65, 52)), class = "data.frame", row.names = c(NA, -7L))

【问题讨论】:

  • 你说第一列是日期,但对我来说,这里的第一列是"2020:01:30,这肯定(对于大多数值)不是日期。您能否提供来自dput(x) 的输出是您数据的前十几行,仅包含相关列?
  • 我编辑了原始描述!
  • 谢谢您,但不幸的是,您使执行所需操作变得更加困难。请不要发布代码/数据/错误的图像:它不能被复制或搜索 (SEO),它会破坏屏幕阅读器,并且它可能不适合某些移动设备。参考:meta.stackoverflow.com/a/285557(和xkcd.com/2116)。请直接包含代码、控制台输出或数据(例如,data.frame(...) 或来自dput(head(x)) 的输出)。 (我建议在 30 秒内进行一次编辑,这将提供两种提供样本数据的首选方法。)
  • 一般来说,您只需要提供我在您的问题中编辑的两种方法之一,前提是我所拥有的两种方法都是不必要的和/或可能令人困惑。但无论是 伟大 使您的问题可重现。

标签: r min


【解决方案1】:

基础 R

bins <- seq(as.POSIXct("2020-01-19 00:30:00", tz = "UTC"), length.out = 5, by = "hour")
bins
# [1] "2020-01-19 00:30:00 UTC" "2020-01-19 01:30:00 UTC" "2020-01-19 02:30:00 UTC"
# [4] "2020-01-19 03:30:00 UTC" "2020-01-19 04:30:00 UTC"
dat$bin <- bins[ findInterval(dat$timestamp, bins) ]
dat
#             timestamp int val                 bin
# 1 2020-01-19 01:30:00   1  25 2020-01-19 01:30:00
# 2 2020-01-19 01:40:00   1  70 2020-01-19 01:30:00
# 3 2020-01-19 01:50:00   1  68 2020-01-19 01:30:00
# 4 2020-01-19 02:00:00   1  53 2020-01-19 01:30:00
# 5 2020-01-19 02:10:00   1  63 2020-01-19 01:30:00
# 6 2020-01-19 02:20:00   1  65 2020-01-19 01:30:00
# 7 2020-01-19 02:30:00   1  52 2020-01-19 02:30:00
aggregate(val ~ bin, data = dat, FUN = min)
#                   bin val
# 1 2020-01-19 01:30:00  25
# 2 2020-01-19 02:30:00  52

如果您需要添加包含该组时间最小值的列(保留行),则

do.call(rbind, by(dat, dat$bin, function(z) transform(z, minval = min(val))))
#                                 timestamp int val                 bin minval
# 2020-01-19 01:30:00.1 2020-01-19 01:30:00   1  25 2020-01-19 01:30:00     25
# 2020-01-19 01:30:00.2 2020-01-19 01:40:00   1  70 2020-01-19 01:30:00     25
# 2020-01-19 01:30:00.3 2020-01-19 01:50:00   1  68 2020-01-19 01:30:00     25
# 2020-01-19 01:30:00.4 2020-01-19 02:00:00   1  53 2020-01-19 01:30:00     25
# 2020-01-19 01:30:00.5 2020-01-19 02:10:00   1  63 2020-01-19 01:30:00     25
# 2020-01-19 01:30:00.6 2020-01-19 02:20:00   1  65 2020-01-19 01:30:00     25
# 2020-01-19 02:30:00   2020-01-19 02:30:00   1  52 2020-01-19 02:30:00     52

tidyverse

library(dplyr)
# using `bins` from above
dat %>%
  mutate(bin = bins[ findInterval(timestamp, bins) ]) %>%
  group_by(bin) %>%
  summarize(val = min(val), .groups = "drop")
# # A tibble: 2 x 2
#   bin                   val
#   <dttm>              <dbl>
# 1 2020-01-19 01:30:00    25
# 2 2020-01-19 02:30:00    52

dat %>%
  mutate(bin = bins[ findInterval(timestamp, bins) ]) %>%
  group_by(bin) %>%
  mutate(minval = min(val)) %>%
  ungroup()
# # A tibble: 7 x 5
#   timestamp             int   val bin                 minval
#   <dttm>              <int> <dbl> <dttm>               <dbl>
# 1 2020-01-19 01:30:00     1    25 2020-01-19 01:30:00     25
# 2 2020-01-19 01:40:00     1    70 2020-01-19 01:30:00     25
# 3 2020-01-19 01:50:00     1    68 2020-01-19 01:30:00     25
# 4 2020-01-19 02:00:00     1    53 2020-01-19 01:30:00     25
# 5 2020-01-19 02:10:00     1    63 2020-01-19 01:30:00     25
# 6 2020-01-19 02:20:00     1    65 2020-01-19 01:30:00     25
# 7 2020-01-19 02:30:00     1    52 2020-01-19 02:30:00     52

数据表

library(data.table)
# using
datDT[, bin := bins[ findInterval(timestamp, bins) ] ][, .(val = min(val)), by = .(bin) ]
#                    bin   val
#                 <POSc> <num>
# 1: 2020-01-19 01:30:00    25
# 2: 2020-01-19 02:30:00    52

datDT[, bin := bins[ findInterval(timestamp, bins) ] ][, minval := min(val), by = .(bin) ]
datDT
#              timestamp   int   val                 bin minval
#                 <POSc> <int> <num>              <POSc>  <num>
# 1: 2020-01-19 01:30:00     1    25 2020-01-19 01:30:00     25
# 2: 2020-01-19 01:40:00     1    70 2020-01-19 01:30:00     25
# 3: 2020-01-19 01:50:00     1    68 2020-01-19 01:30:00     25
# 4: 2020-01-19 02:00:00     1    53 2020-01-19 01:30:00     25
# 5: 2020-01-19 02:10:00     1    63 2020-01-19 01:30:00     25
# 6: 2020-01-19 02:20:00     1    65 2020-01-19 01:30:00     25
# 7: 2020-01-19 02:30:00     1    52 2020-01-19 02:30:00     52

【讨论】:

    猜你喜欢
    • 2020-03-29
    • 1970-01-01
    • 2012-06-03
    • 2012-05-30
    • 2011-08-03
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    • 2019-02-09
    相关资源
    最近更新 更多