【问题标题】:Finding the max and minimum value for a daily series in R?在 R 中找到每日系列的最大值和最小值?
【发布时间】:2023-03-08 17:25:01
【问题描述】:

我有一年的每小时数据,我想找出每天的最大值和最小值。在保留与最大/最小值关联的时间数据的同时,我将如何做呢?我的目标是生成一个图表,以平滑最大/最小值之间的数据点,因此我需要保留与最大/最小值相关联的时间戳列信息。

timestamp        & VALUES   &  &  &  \\
2016-01-01 0:00  & \#VALUE! &  &  &  \\
2016-01-01 1:00  & 2        &  &  &  \\
2016-01-01 2:00  & 0.5      &  &  &  \\
2016-01-01 3:00  & -1       &  &  &  \\
2016-01-01 4:00  & -2       &  &  &  \\
2016-01-01 5:00  & 4        &  &  &  \\
2016-01-01 6:00  & 2        &  &  &  \\
2016-01-01 7:00  & 0        &  &  &  \\
2016-01-01 8:00  & 5        &  &  &  \\
2016-01-01 9:00  & 61.5     &  &  &  \\
2016-01-01 10:00 & 19       &  &  &  \\
2016-01-01 11:00 & 3.5      &  &  &  \\
2016-01-01 12:00 & -1.5     &  &  &  \\
2016-01-01 13:00 & 9        &  &  &  \\
2016-01-01 14:00 & 0.5      &  &  &  \\
2016-01-01 15:00 & 0        &  &  &  \\
2016-01-01 16:00 & -8       &  &  &  \\
2016-01-01 17:00 & 7.5      &  &  &  \\
2016-01-01 18:00 & -9       &  &  &  \\
2016-01-01 19:00 & -80.5    &  &  &  \\
2016-01-01 20:00 & -9       &  &  &  \\
2016-01-01 21:00 & -0.5     &  &  &  \\
2016-01-01 22:00 & -0.5     &  &  &  \\
2016-01-01 23:00 & -2       &  &  & 

提前致谢!

【问题讨论】:

标签: r time-series


【解决方案1】:

timestamp 转换为POSIXct,从中提取日期并为每个日期保留具有最大值和最小值的行。

library(dplyr)
library(lubridate)

result <- df %>%
  mutate(timestamp = mdy_hm(timestamp), 
         date = as.Date(timestamp)) %>%
  arrange(date, VALUES) %>%
  group_by(date) %>%
  slice(1, n())

【讨论】:

  • 您能解释一下arrange()、group_by()、slice() 之后的作用吗?我了解到您正在使用 mutate() 读取和分组时间戳
  • arrange 将按升序对数据进行排序,以便较低的值在前,较高的值在最后。对于每个date (group_by),然后我们选择第一行和最后一行,以便我们获得每个日期的更高和更低的值。
【解决方案2】:

您可以在ave 中使用strftime。为简洁起见,我以 4 小时数据为例

r <- transform(dat, min=ave(values, strftime(timestamp, '%F'), FUN=min),
               max=ave(values, strftime(timestamp, '%F'), FUN=max))
r
#           timestamp values min max
# 1   2016-01-01 0:00    -27 -66  13
# 2   2016-01-01 4:00    -32 -66  13
# 3   2016-01-01 8:00     13 -66  13
# 4  2016-01-01 12:00    -52 -66  13
# 5  2016-01-01 16:00    -66 -66  13
# 6  2016-01-01 20:00     12 -66  13
# 7   2016-01-02 0:00    -19 -53  19
# 8   2016-01-02 4:00     -8 -53  19
# 9   2016-01-02 8:00      8 -53  19
# 10 2016-01-02 12:00     18 -53  19
# 11 2016-01-02 16:00    -53 -53  19
# 12 2016-01-02 20:00     19 -53  19
# 13  2016-01-03 0:00     12 -74  42
# 14  2016-01-03 4:00     27 -74  42
# 15  2016-01-03 8:00    -74 -74  42
# 16 2016-01-03 12:00    -31 -74  42
# 17 2016-01-03 16:00     42 -74  42
# 18 2016-01-03 20:00    -62 -74  42

但是,如果您的数据中有缺失,您将需要一个匿名函数。

dat[7, 2] <- NA

transform(
  dat, 
  min=ave(values, strftime(timestamp, '%F'), FUN=\(x) min(x, na.rm=TRUE)), 
  max=ave(values, strftime(timestamp, '%F'), FUN=\(x) max(x, na.rm=TRUE)))   
#           timestamp values min max
# 1   2016-01-01 0:00    -27 -66  13
# 2   2016-01-01 4:00    -32 -66  13
# 3   2016-01-01 8:00     13 -66  13
# 4  2016-01-01 12:00    -52 -66  13
# 5  2016-01-01 16:00    -66 -66  13
# 6  2016-01-01 20:00     12 -66  13
# 7   2016-01-02 0:00     NA -53  19
# 8   2016-01-02 4:00     -8 -53  19
# 9   2016-01-02 8:00      8 -53  19
# 10 2016-01-02 12:00     18 -53  19
# 11 2016-01-02 16:00    -53 -53  19
# 12 2016-01-02 20:00     19 -53  19
# 13  2016-01-03 0:00     12 -74  42
# 14  2016-01-03 4:00     27 -74  42
# 15  2016-01-03 8:00    -74 -74  42
# 16 2016-01-03 12:00    -31 -74  42
# 17 2016-01-03 16:00     42 -74  42
# 18 2016-01-03 20:00    -62 -74  42

POSIXct 格式的真实时间戳会更漂亮。

r <- transform(dat, timestamp=as.POSIXct(timestamp),
               min=ave(values, strftime(timestamp, '%F'), FUN=min),
               max=ave(values, strftime(timestamp, '%F'), FUN=max))
r
#              timestamp values min max
# 1  2016-01-01 00:00:00    -27 -66  13
# 2  2016-01-01 04:00:00    -32 -66  13
# 3  2016-01-01 08:00:00     13 -66  13
# 4  2016-01-01 12:00:00    -52 -66  13
# 5  2016-01-01 16:00:00    -66 -66  13
# 6  2016-01-01 20:00:00     12 -66  13
# 7  2016-01-02 00:00:00     NA  NA  NA
# 8  2016-01-02 04:00:00     -8  NA  NA
# 9  2016-01-02 08:00:00      8  NA  NA
# 10 2016-01-02 12:00:00     18  NA  NA
# 11 2016-01-02 16:00:00    -53  NA  NA
# 12 2016-01-02 20:00:00     19  NA  NA
# 13 2016-01-03 00:00:00     12 -74  42
# 14 2016-01-03 04:00:00     27 -74  42
# 15 2016-01-03 08:00:00    -74 -74  42
# 16 2016-01-03 12:00:00    -31 -74  42
# 17 2016-01-03 16:00:00     42 -74  42
# 18 2016-01-03 20:00:00    -62 -74  42

数据:

dat <- structure(list(timestamp = c("2016-01-01 0:00", "2016-01-01 2:00", 
"2016-01-01 4:00", "2016-01-01 6:00", "2016-01-01 8:00", "2016-01-01 10:00", 
"2016-01-01 12:00", "2016-01-01 14:00", "2016-01-01 16:00", "2016-01-01 18:00", 
"2016-01-01 20:00", "2016-01-01 22:00", "2016-01-02 0:00", "2016-01-02 2:00", 
"2016-01-02 4:00", "2016-01-02 6:00", "2016-01-02 8:00", "2016-01-02 10:00", 
"2016-01-02 12:00", "2016-01-02 14:00", "2016-01-02 16:00", "2016-01-02 18:00", 
"2016-01-02 20:00", "2016-01-02 22:00", "2016-01-03 0:00", "2016-01-03 2:00", 
"2016-01-03 4:00", "2016-01-03 6:00", "2016-01-03 8:00", "2016-01-03 10:00", 
"2016-01-03 12:00", "2016-01-03 14:00", "2016-01-03 16:00", "2016-01-03 18:00", 
"2016-01-03 20:00", "2016-01-03 22:00"), values = c(7, 12, NA, 
-70, -4, -22, -13, -76, 13, 45, 48, 55, -64, -30, -20, -8, -10, 
40, -32, 3, -67, -66, -74, -75, 57, 16, -31, -17, 9, 7, -66, 
13, 41, 58, 26, 58)), class = "data.frame", row.names = c(NA, 
-36L))

【讨论】:

    猜你喜欢
    • 2014-12-15
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2018-03-12
    • 2020-06-20
    • 1970-01-01
    相关资源
    最近更新 更多