如何解决dplyr :: if_else更改日期时间POSIXct值
我正在处理带有大量时间戳记的数据集。我尝试识别一些无效的时间戳并将其设置为NA。因为if_else()
迫使我在双臂上具有相同的数据类型,所以我使用as.POSIXct(NA)
来编码这样的缺失值。
有趣的是,当我在true
中反转测试(并更改false
和if_else()
参数)时,结果会有所不同。
下面是一些代码来说明我的问题:
x <- tibble(
A = parse_datetime("2020-08-18 19:00"),B = if_else(TRUE,A,as.POSIXct(NA)),C = if_else(FALSE,as.POSIXct(NA),A)
)
> x
# A tibble: 1 x 3
A B C
<dttm> <dttm> <dttm>
1 2020-08-18 19:00:00 2020-08-18 19:00:00 2020-08-18 21:00:00
任何想法,为什么C在两个小时后出现?
跟进:
基于以下出色的答案,我认为一种更具可读性的解决方案也许应该使用parse_datetime(NA_character_)
生成缺少的datetime对象,并在代码中而不是as.POSIXct()
中使用它。
R> NA_datetime_ <- parse_datetime(NA_character_)
R> x <- tibble(
A = parse_datetime("2020-08-18 19:00"),NA_datetime_),NA_datetime_,A)
)
R> map(x,lubridate::tz)
$A
[1] "UTC"
$B
[1] "UTC"
$C
[1] "UTC"
解决方法
首先,您需要知道parse_datetime()
返回一个日期时间对象,该对象的tzone
属性默认为UTC
。您可以使用lubridate::tz(x$A)
和attributes(x$A)
进行检查。
在if_else()
的文档中,它说true
和false
参数必须是同一类型。 所有其他属性均取自true
。因此,在您的小标题的C
部分:
C = if_else(FALSE,as.POSIXct(NA),A)
as.POSIXct(NA)
没有tzone
属性,因此A
的{{1}}被删除并重置为您所在地区的时区。实际上,tzone
是两个小时后 不是 。 这三列的时间相等,但时区不相等。要解决此问题,您可以将C
调整为拥有as.POSIXct(NA)
属性,即将其替换为
tzone
注意: 您必须使用as.POSIXct(NA_character_,tz = "UTC")
而不是NA_character_
,因为{{1}中的NA
参数}仅适用于角色对象。
最后,将您的代码修改为
tz
记住要检查他们的时区。
as.POSIXct()
,
这是时区问题:
lubridate::tz(x$A)
[1] "UTC"
lubridate::tz(x$B)
[1] "UTC"
lubridate::tz(x$C)
[1] ""
这是由于if_else <- function (test,yes,no)
的工作方式:它使用yes
参数的属性,对于C,该属性是NA
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。