r - 聚合函数和时区

标签 r dplyr timezone aggregate posixct

我有两段代码理论上可以做同样的事情:

Mn_min_max_D <- with(Mn, aggregate(Depth ~ as.Date(Date_time), FUN =  function(x) c(Min = min(x), Max = max(x))))
Mn_min_max_D <- do.call(data.frame, Mn_min_max_D)
names(Mn_min_max_D)[names(Mn_min_max_D) == "as.Date.Date_time."] <- "Date"

min_max_D <- with(Mn, aggregate(Depth ~ as.Date(Date), FUN =  function(x) c(Min = min(x), Max = max(x))))
min_max_D <- do.call(data.frame, min_max_D)
names(Mn_min_max_D)[names(min_max_D) == "as.Date.Date_time."] <- "Date"

但是输出值不同。在检查最大深度时,我可以看到由于某种原因,第一段代码中时区被忽略。 例如,最大深度发生在“2013-10-26 22:33:00”,但经过时区校正,这实际上是“2013-10-27 07:33:00”。

$Date 值来自此代码:

Mn$Date_time <- as.POSIXct(Mn$Date_time, format="%Y-%m-%d %H:%M:%S", tz = "Asia/Tokyo")
    Mn$Date <- format(as.POSIXct(Mn$Date_time, format="%YYYY/%m/%d %H:%M:%S"), format = "%Y/%m/%d")
    Mn$Date <- as.Date(Mn$Date, "%Y/%m/%d")

看起来也许删除时间的过程可以修复日期。我需要了解问题的根源,以确保我将来不会犯错误。

我想我可能需要用 tz 进行 %>% 变异,但目前不明白如何操作。或者也许使用 dplyr 来聚合,如下所示,但我已经尝试过,结果是相同的。

test <- Mn %>% group_by(as.Date(Date_time))%>% dplyr::summarise(min = min(Depth), max = max(Depth))

示例数据:

Date_time Depth
2013-10-14 12:30:00 64.45
2013-10-14 12:30:05 65.95
2013-10-14 12:30:10 65.95
2013-10-14 12:30:15 66.45
2013-10-14 12:30:20 67.95
2013-10-14 12:30:25 66.95

最佳答案

在当前格式中,数据不包含时区,因此使用默认时区。如果您知道这些时间戳的时区,最好明确地控制它。

dta <- with(
    asNamespace("readr"),
    read_table(
        file = "
Date_time Depth
2013-10-14-12:30:00 64.45
2013-10-14-12:30:05 65.95
2013-10-14-12:30:10 65.95
2013-10-14-12:30:15 66.45
2013-10-14-12:30:20 67.95
2013-10-14-12:30:25 66.95",
col_types = cols(
    Date_time = col_datetime(format = "%Y-%m-%d-%H:%M:%S"),
    Depth = col_double()
)
    )
)

library("lubridate")
library("tidyverse")
dta %>%
    mutate(DT_tz = force_tz(Date_time, tzone = "GMT"),
           DT_tz_NYC = with_tz(Date_time, tzone = "America/New_York"))

说明

考虑以下因素:

  • tz(now()) 返回空字符串
  • Sys.timezone() 返回本地时区,在我的例子中为“欧洲/伦敦”
  • tz(as.Date(now())) 返回“UTC”

如果不指定时区,R 将取决于您的本地设置

as.POSIXlt(Sys.time(), "America/New_York")
# "2022-03-18 12:43:10 EDT"
as.POSIXlt(Sys.time())
# "2022-03-18 16:43:16 GMT"

这可能会有点麻烦。

tz(as.POSIXlt(Sys.time()))
# [1] "Europe/London"
tz(as.Date(as.POSIXlt(Sys.time())))
# "UTC"

特别值得一提的是,使用 as.Date 将删除时区信息。

tz(as.Date(as.POSIXlt(Sys.time())))
"UTC"
tz(as.Date(as.POSIXlt(Sys.time()), tz = "Africa/Abidjan"))
"UTC"

解决方案

如果处理时间戳,始终建议确保时区信息在该数据中重新编码,或者作为替代方案,在脚本中明确说明,该选项不太健壮。就我个人而言,我认为时区组件是时间戳的组成部分,并且应该与数据一起驻留。当本地时间戳不同时,从时间戳中剥离时区信息会导致困惑。显着差异可能会导致日期不同(考虑 2 小时时区差异以及接近午夜发生的事件等)。

关于r - 聚合函数和时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71527832/

相关文章:

r - 与data.table分组时,如何保留未出现在输入数据中的变量组合?

python - 在 R 中加载 pickle

r - 使用dplyr的summarise_each每个函数返回一行?

c# - 我想在 EST 中初始化 DateTime,然后转换为 Universal TIme

python - 将 tzinfo 设置为日期时间对象的最佳实践或快捷方式

r - 无法安装 gmum.r 包

r - 如何将公式对象处理为字符对象?

r - 使用 bind_cols (r, dplyr) 时设置列名

在 r 中使用 rename_at 从列名中删除后缀

python - 如何比较python中的两个时区?