R:if_else和时区强制

问题描述 投票:1回答:1

我有一个奇怪的问题(也许我遗漏了什么?),当试图在if_else内强制时区时(因为ifelse似乎不能很好地处理POSIXct)。它似乎仅在TRUE时有效,而在FALSE时才转换。为什么?如何解决?

library(lubridate)
library(dplyr)
some_date = ymd_hm("2020-06-01 17:45", tz = "America/New_York")

if_else(TRUE, force_tz(some_date, tz = "GMT"), force_tz(some_date, tz = "Singapore"))
[1] "2020-06-01 17:45:00 GMT"

if_else(FALSE, force_tz(some_date, tz = "GMT"), force_tz(some_date, tz = "Singapore"))
[1] "2020-06-01 09:45:00 GMT"

我期望与单独运行force_tz的结果相同:

# if TRUE
force_tz(some_date, tz = "GMT")
[1] "2020-06-01 17:45:00 GMT"

# if FALSE
force_tz(some_date, tz = "Singapore")
[1] "2020-06-01 17:45:00 +08"

谢谢!

r if-statement lubridate posixct
1个回答
2
投票

罪魁祸首在方式 dplyr::if_else进行调整。

首先,我对向量和TZ的原始评论仍然存在,并且仍然是这个问题的核心。记录:

当处理vector中的POSIXt时,TZ是整个向量的属性,而不是每个独立元素。这意味着(a)您必须接受向量中的所有时间戳都将具有相同的TZ;或(b)您需要调整流程以处理list的时间戳,在这种情况下,每次都可以拥有自己的TZ。

如果您查看if_else

function (condition, true, false, missing = NULL) 
{
    if (!is.logical(condition)) {
        bad_args("condition", "must be a logical vector, not {friendly_type_of(condition)}")
    }
    out <- true[rep(NA_integer_, length(condition))]

使用第一个(“ true”)向量的out个变体预填充NA向量。 (这是必要的,因为R实际上至少有6种NA类型:逻辑(NA),整数(NA_integer_),实数/浮点数(NA_real_),字符串(NA_character_),日期([ C0])和时间(c.Date(NA));因此形成c.POSIXct(NA)向量的[[how很重要。)但是,一旦预先填充NA s的向量,就应意识到这是基于第一个向量,因此将其属性带到NA向量中。

out
((请参阅Sys.time()
# [1] "2020-06-01 09:02:06 PDT"
now <- Sys.time()
attr(now, "tzone") <- "GMT"
dput(now)
# structure(1591027335.41804, class = c("POSIXct", "POSIXt"), tzone = "GMT")
dput(now[NA])
# structure(NA_real_, class = c("POSIXct", "POSIXt"), tzone = "GMT")
仍然如何)。这意味着输出向量(当对tzone=个向量进行操作时)POSIXt truewill always carry forward the TZ of theif_else`。

从这里开始,argument to

替换

中工作(使用其内部的if_else,实际上是replace_with)。替换<out[condition] <- false[condition]次的数值等效项是同化的,而不考虑其TZ。当然,false向量的“世界绝对时间”被保留。唯一的解决方法是更改​​您的工作流程以处理falselist而不是向量。 POSIXt仍在那儿工作。if_else
© www.soinside.com 2019 - 2024. All rights reserved.