【问题标题】:Reducing time series data from half hour to hourly in R在 R 中将时间序列数据从半小时减少到每小时
【发布时间】:2019-12-18 15:44:12
【问题描述】:

我正在处理半小时分辨率的智能电表数据。由于数据量巨大,我正试图从半小时分辨率减少到每小时分辨率。在这样做时,我试图将两个半小时测量之间的消耗相加。问题是我的数据框中也有分类数据,在使用 xts 时会丢失。这是我的数据的样子:

> head(test1)
      LCLid stdorToU            DateTime KWH.hh..per.half.hour.   Acorn Acorn_grouped
1 MAC000002      Std 2012-10-12 00:30:00                      0 ACORN-A      Affluent
2 MAC000002      Std 2012-10-12 01:00:00                      0 ACORN-A      Affluent
3 MAC000002      Std 2012-10-12 01:30:00                      0 ACORN-A      Affluent
4 MAC000002      Std 2012-10-12 02:00:00                      0 ACORN-A      Affluent
5 MAC000002      Std 2012-10-12 02:30:00                      0 ACORN-A      Affluent
6 MAC000002      Std 2012-10-12 03:00:00                      0 ACORN-A      Affluent

这是我一直在尝试使用的代码和我得到的结果。

test1 <- read.csv("test.csv", stringsAsFactors = F)
test1$DateTime <- ymd_hms(test1$DateTime)
test1$KWH.hh..per.half.hour. <- as.numeric(test1$KWH.hh..per.half.hour.)
test2 <- xts(test1$KWH.hh..per.half.hour., test1$DateTime)
head(test2)
period.apply(test2, endpoints(test2, "hours"), sum)

> period.apply(test2, endpoints(test2, "hours"), sum)
                     [,1]
2012-10-12 00:30:00 0.000
2012-10-12 01:30:00 0.000
2012-10-12 02:30:00 0.000
2012-10-12 03:30:00 0.000
2012-10-12 04:30:00 0.000
2012-10-12 05:30:00 0.000
2012-10-12 06:30:00 0.000
2012-10-12 07:30:00 0.000
2012-10-12 08:30:00 0.000
2012-10-12 09:30:00 0.000
2012-10-12 10:30:00 0.000

理想情况下,我需要一个与原始数据集 (test1) 完全相同的数据集,只是按每小时而不是每半小时汇总的一半大小。有人可以帮忙吗?

谢谢

【问题讨论】:

    标签: r time-series


    【解决方案1】:

    你需要创建一个分组列,然后按组求和。

    # create grouped column
    test1$grouped_time = lubridate::floor_date(test1$DateTime, unit = "hour")
    # (use ceiling_date instead if you want to round the half hours up instead of down)
    
    # sum by group
    library(dplyr)
    test2 = test1 %>%
      group_by(grouped_time, LCLid, stdorToU, Acorn, Acorn_grouped) %>%
      summarize(KWH.hh.per.hour = sum(KWH.hh..per.half.hour.))
    

    Sum by Group R-FAQ 有很多 dplyr 的替代品,如果您想查看更多选项。

    请注意,这将对group_by() 中其他列的每个唯一组合的 KWH 列求和。如果其中一些可以更改,例如 stdorToUACORN 值可能会从一个小时到下一个半小时更改,但您仍然希望合并行,则需要将该列移出 group_by 并移入 @ 987654328@,并指定要保留的值,例如

    # if ACORN can change and you want to keep the first one
    test2 = test1 %>%
      group_by(grouped_time, LCLid, stdorToU, Acorn_grouped) %>%
      summarize(KWH.hh.per.hour = sum(KWH.hh..per.half.hour.),
                ACORN = first(ACORN))
    

    【讨论】:

    • Gregor,工作得很好,虽然有趣的是,这个时间是 00:00:00 的每个小时在数据框中不存在,只是日期。几乎就像 R 认为时间为零一样。在运行“grouped_by”之前情况并非如此。有什么想法吗?
    • 嗯,我无法复制。如果您使用dput 分享您的一点数据,例如dput(droplevels(test1[1:10, ])),我希望能看到您所看到的。 (选择与前 10 行不同的子集,以确保包含 00:00:00 示例)
    • 我在下面的答案中发表了评论(抱歉,我不确定在哪里添加这么长的回复)。变量名称已经改变,因为在它开始工作后我使用了整个数据集而不是较小的测试集
    • 在您的问题中包含一些dput 是一个很好的做法,这是最好的地方。
    • 谢谢格雷戈尔。我是数据科学的新手,能有像你这样的人帮我解决这些问题真是太好了。
    【解决方案2】:
    > head(sm_2013_tof)
    # A tibble: 6 x 6
    # Groups:   grouped_time, LCLid, stdorToU, Acorn [6]
      grouped_time        LCLid     stdorToU Acorn   Acorn_grouped KWH.hh.per.hour
      <dttm>              <chr>     <chr>    <chr>   <chr>                   <dbl>
    1 2013-01-01 00:00:00 MAC000146 ToU      ACORN-L Adversity               0.155
    2 2013-01-01 00:00:00 MAC000147 ToU      ACORN-F Comfortable             0.276
    3 2013-01-01 00:00:00 MAC000158 ToU      ACORN-H Comfortable             0.152
    4 2013-01-01 00:00:00 MAC000165 ToU      ACORN-E Affluent                0.401
    5 2013-01-01 00:00:00 MAC000170 ToU      ACORN-F Comfortable             0.64 
    6 2013-01-01 00:00:00 MAC000173 ToU      ACORN-E Affluent                0.072
    > 
    

    这是分组后的每小时数据。

    如果我将其设为 as.data.frame,您会看到 00:00:00 消失了

    sm_short_2013 &lt;- as.data.frame(sm_2013_tof)

    > head(sm_short_2013)
      grouped_time     LCLid stdorToU   Acorn Acorn_grouped KWH.hh.per.hour
    1   2013-01-01 MAC000146      ToU ACORN-L     Adversity           0.155
    2   2013-01-01 MAC000147      ToU ACORN-F   Comfortable           0.276
    3   2013-01-01 MAC000158      ToU ACORN-H   Comfortable           0.152
    4   2013-01-01 MAC000165      ToU ACORN-E      Affluent           0.401
    5   2013-01-01 MAC000170      ToU ACORN-F   Comfortable           0.640
    6   2013-01-01 MAC000173      ToU ACORN-E      Affluent           0.072
    
    > dput(droplevels(sm_short_2013[1:10, ]))
    structure(list(grouped_time = structure(c(1356998400, 1356998400, 
    1356998400, 1356998400, 1356998400, 1356998400, 1356998400, 1356998400, 
    1356998400, 1356998400), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
        LCLid = c("MAC000146", "MAC000147", "MAC000158", "MAC000165", 
        "MAC000170", "MAC000173", "MAC000186", "MAC000187", "MAC000193", 
        "MAC000194"), stdorToU = c("ToU", "ToU", "ToU", "ToU", "ToU", 
        "ToU", "ToU", "ToU", "ToU", "ToU"), Acorn = c("ACORN-L", 
        "ACORN-F", "ACORN-H", "ACORN-E", "ACORN-F", "ACORN-E", "ACORN-E", 
        "ACORN-L", "ACORN-D", "ACORN-D"), Acorn_grouped = c("Adversity", 
        "Comfortable", "Comfortable", "Affluent", "Comfortable", 
        "Affluent", "Affluent", "Adversity", "Affluent", "Affluent"
        ), KWH.hh.per.hour = c(0.155, 0.276, 0.152, 0.401, 0.64, 
        0.072, 0.407, 0.554, 0.725, 0.158)), row.names = c(NA, 10L
    ), class = "data.frame")
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-05
      • 2015-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-10
      • 1970-01-01
      相关资源
      最近更新 更多