在 R 中使用 dplyr::if_else() 根据另一个变量的值更改 POSIXct 时间戳的时区
Using dplyr::if_else() in R to change the time zone of POSIXct timestamps based on value of another variable
我正在处理一些 POSIXct 格式的时间戳。现在它们都显示为处于 "UTC" 时区,但实际上有些已知处于 "America/New_York" 时区。我想更正时间戳,以便它们都被读取为正确的时间。
我最初使用 ifelse()
语句和 lubridate::with_tz()
。这没有按预期工作,因为 ifelse()
没有 return POSIXct 中的值。
然后我根据此处的其他帖子尝试 dplyr::if_else()
,但也没有按预期工作。
我可以使用 with_tz()
将单个时间戳甚至时间戳列表更改为不同的时区(所以我知道它有效),但是当我在 if_else()
中使用它时,输出是这样的给定 "yes" 参数 in if_else()
.
所有值都是 returned
library(lubridate)
library(dplyr)
x <- data.frame("ts" = as.POSIXct(c("2017-04-27 13:44:00 UTC",
"2017-03-10 12:22:00 UTC", "2017-03-22 10:24:00 UTC"), tz = "UTC"),
"tz" = c("UTC","EST","UTC"))
x <- mutate(x, ts_New = if_else(tz == "UTC", with_tz(ts, "America/New_York"), ts))
预期结果低于 ts_New 将时间戳调整为新时区,但仅当 tz = "UTC" 中的值时。 tz = "America/New_York" 的时间戳不应更改。
ts tz ts_NEW
1 2017-04-27 13:44:00 UTC 2017-04-27 09:44:00
2 2017-03-10 12:22:00 EST 2017-03-10 12:22:00
3 2017-01-22 10:24:00 UTC 2017-03-22 06:24:00
实际结果低于所有 ts_New 时间戳都调整到新时区的位置,无论 tz
中的值如何
x
ts tz ts_New
1 2017-04-27 13:44:00 UTC 2017-04-27 09:44:00
2 2017-03-10 12:22:00 EST 2017-03-10 07:22:00
3 2017-03-22 10:24:00 UTC 2017-03-22 06:24:00
这并没有回答您关于为什么 with_tz
不适用于 if_else
的原始问题,但这是一种解决方法。我们减去 4 小时(UTC 和 EST 之间的差异),其中 tz == "UTC"
.
library(dplyr)
library(lubridate)
x %>% mutate(ts_New = if_else(tz == "UTC", ts - hours(4), ts))
# ts tz ts_New
#1 2017-04-27 13:44:00 UTC 2017-04-27 09:44:00
#2 2017-03-10 12:22:00 EST 2017-03-10 12:22:00
#3 2017-03-22 10:24:00 UTC 2017-03-22 06:24:00
或以 R 为基数
x$ts_New <- x$ts
inds <- x$tz == "UTC"
x$ts_New[inds] <- x$ts_New[inds] - 4 * 60 * 60
我正在处理一些 POSIXct 格式的时间戳。现在它们都显示为处于 "UTC" 时区,但实际上有些已知处于 "America/New_York" 时区。我想更正时间戳,以便它们都被读取为正确的时间。
我最初使用 ifelse()
语句和 lubridate::with_tz()
。这没有按预期工作,因为 ifelse()
没有 return POSIXct 中的值。
然后我根据此处的其他帖子尝试 dplyr::if_else()
,但也没有按预期工作。
我可以使用 with_tz()
将单个时间戳甚至时间戳列表更改为不同的时区(所以我知道它有效),但是当我在 if_else()
中使用它时,输出是这样的给定 "yes" 参数 in if_else()
.
library(lubridate)
library(dplyr)
x <- data.frame("ts" = as.POSIXct(c("2017-04-27 13:44:00 UTC",
"2017-03-10 12:22:00 UTC", "2017-03-22 10:24:00 UTC"), tz = "UTC"),
"tz" = c("UTC","EST","UTC"))
x <- mutate(x, ts_New = if_else(tz == "UTC", with_tz(ts, "America/New_York"), ts))
预期结果低于 ts_New 将时间戳调整为新时区,但仅当 tz = "UTC" 中的值时。 tz = "America/New_York" 的时间戳不应更改。
ts tz ts_NEW
1 2017-04-27 13:44:00 UTC 2017-04-27 09:44:00
2 2017-03-10 12:22:00 EST 2017-03-10 12:22:00
3 2017-01-22 10:24:00 UTC 2017-03-22 06:24:00
实际结果低于所有 ts_New 时间戳都调整到新时区的位置,无论 tz
中的值如何x
ts tz ts_New
1 2017-04-27 13:44:00 UTC 2017-04-27 09:44:00
2 2017-03-10 12:22:00 EST 2017-03-10 07:22:00
3 2017-03-22 10:24:00 UTC 2017-03-22 06:24:00
这并没有回答您关于为什么 with_tz
不适用于 if_else
的原始问题,但这是一种解决方法。我们减去 4 小时(UTC 和 EST 之间的差异),其中 tz == "UTC"
.
library(dplyr)
library(lubridate)
x %>% mutate(ts_New = if_else(tz == "UTC", ts - hours(4), ts))
# ts tz ts_New
#1 2017-04-27 13:44:00 UTC 2017-04-27 09:44:00
#2 2017-03-10 12:22:00 EST 2017-03-10 12:22:00
#3 2017-03-22 10:24:00 UTC 2017-03-22 06:24:00
或以 R 为基数
x$ts_New <- x$ts
inds <- x$tz == "UTC"
x$ts_New[inds] <- x$ts_New[inds] - 4 * 60 * 60