在R中使用dplyr :: if_else()基于另一个变量的值更改POSIXct时间戳的时区

KTr*_*per 6 timestamp r posixct lubridate dplyr

我正在使用POSIXct格式的一些时间戳。目前,它们都显示在“ UTC”时区中,但实际上有些已知处于“ America / New_York”时区中。我想更正时间戳,以便它们都读为正确的时间。

我最初使用和ifelse()一起声明lubridate::with_tz()。这没有按预期方式工作,因为ifelse()未在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))
Run Code Online (Sandbox Code Playgroud)

预期结果低于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
Run Code Online (Sandbox Code Playgroud)

实际结果低于所有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
Run Code Online (Sandbox Code Playgroud)

Ron*_*hah 4

这并没有回答您最初关于为什么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
Run Code Online (Sandbox Code Playgroud)

或者以 R 为基数

x$ts_New <- x$ts
inds <- x$tz == "UTC"
x$ts_New[inds] <- x$ts_New[inds] - 4 * 60 * 60
Run Code Online (Sandbox Code Playgroud)