R方法通过将整个数据集向上移动一个小时/向下移动一个小时半年来将标准转换为夏令时?

Posted

技术标签:

【中文标题】R方法通过将整个数据集向上移动一个小时/向下移动一个小时半年来将标准转换为夏令时?【英文标题】:R method to shift standard to daylight savings time by shifting entire dataset up an hour/down an hour for half the year? 【发布时间】:2021-03-06 15:37:33 【问题描述】:

关于夏令时转换和 posixct/posixlt、date.time 等有很多问题,但我发现没有一个问题可以解决我的夏令时方法。

我对分析能源使用的每日负载曲线很感兴趣,而仅将春季时间从数据集中剔除的方法对我不起作用。我需要一种方法,将所有测量值转移到春季夏令时后的下一小时和秋季调整后的前一小时。请参阅下面的一个清晰示例。


EnergyUse <- data.table("Date"= c("1997-04-06", "1997-04-06", "1997-04-06", "1997-04-06"), "Hour"= 1:4, "Power"=c(30,40,60,80))

print(EnergyUse)
#             Date   Hour     Power
#1:     1997-04-06      1        30
#2:     1997-04-06      2        40 #when daylight savings kicked in for 1997
#3:     1997-04-06      3        60
#4:     1997-04-06      4        80

“小时”字段的范围从 0 到 23 表示一年中的每一天,即“当地标准时间”。正如您将在下面看到的那样,它恰好是太平洋时间,但对于任何实施夏令时的时区,我都会有同样的问题。

现在我需要将日期和时间字段合并到格式化为日期和时间并结合夏令时的单个 date_time 字段中,因为我对每小时功率模式(即负载曲线)感兴趣,它会根据相对时间(例如人们上班/下班的时间)和绝对时间(例如,当天气变冷/变热或日落时)。

EnergyUseAdj <- EnergyUse[, Date_Time := as.POSIXct(paste(Date, Hour), format="%Y-%m-%d %H", tz="America/Los_Angeles")]

导致:

print(EnergyUseAdj)

#         Date Hour  Power            Date_Time
#1: 1997-04-06    1     30  1997-04-06 01:00:00
#2: 1997-04-06    2     40                 <NA>
#3: 1997-04-06    3     60  1997-04-06 03:00:00
#4: 1997-04-06    4     80  1997-04-06 04:00:00

但是,这会导致新的夏令时凌晨 3 点和凌晨 4 点的“功率”数据不正确。日光调整后凌晨 3 点的实际发电量数字将改为标准时间凌晨 2 点列出的值(即 40),而凌晨 4 点的实际发电量则为 60。

对此进行调整的正确方法是,将整个时间序列调整为春季 1 小时的正偏移和秋季 1 小时的负偏移,例如下面:

#         Date Hour  Power            Date_Time
#1: 1997-04-06    1     30  1997-04-06 01:00:00
#2: 1997-04-06    2   <NA>                 <NA>
#3: 1997-04-06    3     40  1997-04-06 03:00:00
#4: 1997-04-06    4     60  1997-04-06 04:00:00

或者,由于缺少 NA 线,在其他算法中使用可能更平滑,如下所示:

#         Date Hour  Power            Date_Time
#1: 1997-04-06    1     30  1997-04-06 01:00:00
#2: 1997-04-06    3     40  1997-04-06 03:00:00
#3: 1997-04-06    4     60  1997-04-06 04:00:00
#4: 1997-04-06    5     80  1997-04-06 05:00:00

在玩弄了 Posixct 并阅读了有关此调整的一堆类似问题之后,我找不到一个很好的解决方案。有什么想法吗?

编辑:GregorThomas 的请求,如果您希望使用两天的价值,请参阅下面的更大数据样本。

#       OP_DATE OP_HOUR Power
# 1: 1997-04-05       0    71
# 2: 1997-04-05       1    61
# 3: 1997-04-05       2    54
# 4: 1997-04-05       3    57
# 5: 1997-04-05       4    68
# 6: 1997-04-05       5    76
# 7: 1997-04-05       6    89
# 8: 1997-04-05       7   106
# 9: 1997-04-05       8   148
#10: 1997-04-05       9   154
#11: 1997-04-05      10   143
#12: 1997-04-05      11   123
#13: 1997-04-05      12   105
#14: 1997-04-05      13    94
#15: 1997-04-05      14    85
#16: 1997-04-05      15    86
#17: 1997-04-05      16    84
#18: 1997-04-05      17    83
#19: 1997-04-05      18    99
#20: 1997-04-05      19   105
#21: 1997-04-05      20    94
#22: 1997-04-05      21    95
#23: 1997-04-05      22    81
#24: 1997-04-05      23    66
#25: 1997-04-06       0    75
#26: 1997-04-06       1    70
#27: 1997-04-06       2    62
#28: 1997-04-06       3    56
#29: 1997-04-06       4    55
#30: 1997-04-06       5    57
#31: 1997-04-06       6    51
#32: 1997-04-06       7    57
#33: 1997-04-06       8    59
#34: 1997-04-06       9    61
#35: 1997-04-06      10    64
#36: 1997-04-06      11    63
#37: 1997-04-06      12    63
#38: 1997-04-06      13    63
#39: 1997-04-06      14    60
#40: 1997-04-06      15    68
#41: 1997-04-06      16    69
#42: 1997-04-06      17    69
#43: 1997-04-06      18    91
#44: 1997-04-06      19   120
#45: 1997-04-06      20   100
#46: 1997-04-06      21    74
#47: 1997-04-06      22    56
#48: 1997-04-06      23    55

【问题讨论】:

您能分享从1997-04-05 Hour 221997-04-7 Hour 2 的样本数据吗?您的数据在时间上是否完整(每小时、每天 1 行)?我想您实际上在春季的 DST 日有 0-22 小时,在秋季的 DST 日有 0-24 小时,对吗?假设您要同时处理这两种情况,那么分享一个秋季 DST 日的示例可能也很好...... 我要去的地方是,如果您的数据具有正确的测量次数,而不是进行调整,您可以按小时生成一系列 POSIX 时间并添加它们,而不是做任何类型的转换。例如,seq(as.POSIXct("1997-04-05 22:00:00"), as.POSIXct("1997-04-07 02:00:00"), by = "1 hour") 工作正常(如果您在使用 DST 的语言环境中 - 我们会为可通用代码相应地设置它) @GregorThomas 感谢您的回复。整个数据集每天正好有 24 小时测量 (0-23),因为它是标准时间(没有 DST 班次)。因此,确实需要将数据调整为夏令时。据我所知,秋季的方法应该与春季的方法相反。 我认为显示完整的天数以及前一天和后一天的数据会有助于理解。如果您全年的小时数合适,那么在我的第二条评论中添加seq 方法应该可以正常工作。 24 * 365 = 8760。length(seq(as.POSIXct("1997-01-01 00:00:00"), as.POSIXct("1997-12-31 23:00:00"), by = "1 hour")) 也是 8760。从你的第一个日期时间到最后一个日期时间使用seq,并让seq 填写中间。 【参考方案1】:

如果您的数据是可靠的每小时,您可以计算适当长度的小时序列。 POSIX 日期时间的实现考虑了夏令时、闰年等。

在我的评论中简化方法,我建议根据开始时间和长度计算序列。

EnergyUseAdj <- EnergyUse[,
  Date_Time := seq(
    from = as.POSIXct(paste(Date[1], Hour[1]), format="%Y-%m-%d %H", tz="America/Los_Angeles"),
    length.out = .N,
    by = "1 hour"
  )]

【讨论】:

感谢您在此处发布答案。这非常有效。对于那些好奇且对data.table语法不太熟悉的人,如果您需要对排序进行分组(例如每个Column1-Column 2组合有自己的全套日期时间,需要独立排序,就像我的数据集的动力装置一样)。只需确保 data.table 已按 Column1、Column2、日期和时间排序,以便在分组时正确排序。

以上是关于R方法通过将整个数据集向上移动一个小时/向下移动一个小时半年来将标准转换为夏令时?的主要内容,如果未能解决你的问题,请参考以下文章

在列表框中向上或向下移动项目

如何将整个 div 元素向上移动 x 个像素?

如何在jQuery中移动表格行?

使用javascript在dom树中向上或向下移动一个元素

jQuery 可排序的向上/向下移动按钮

Vi编辑器的使用