使用 as.Date 和 as_date 将 `dttm` 转换为 `date` 格式在 R 中给出不同的结果
Converting `dttm` to `date` formatting with as.Date and as_date give different results in R
我有一个大型数据集,其中包含事件时间和日期的各个列。我最终创建了一个包含时间和日期的主 dttm
对象,但是当我尝试根据日期进行过滤时遇到了麻烦。这是反映我自己的示例数据集:
library(tidyverse)
d<- structure(list(date = structure(c(1530921600, 1531008000,
1530403200, 1530489600, 1530576000, 1530489600, 1530576000, 1531008000,
1530921600, 1530662400, 1530748800, 1531180800, 1530748800, 1531526400,
1531526400, 1532044800, 1532131200, 1531180800, 1531353600, 1531353600
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), date_time = structure(c(1531019100,
1531117500, 1530440640, 1530562440, 1530633240, 1530571920, 1530648900,
1531037100, 1531010460, 1530717240, 1530808200, 1531237020, 1530813000,
1531614060, 1531637640, 1532104320, 1532195220, 1531290120, 1531434300,
1531409280), class = c("POSIXct", "POSIXt"), tzone = "")), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -20L))
数据如下:
# A tibble: 20 x 2
date date_time
<dttm> <dttm>
1 2018-07-07 00:00:00 2018-07-07 20:05:00
2 2018-07-08 00:00:00 2018-07-08 23:25:00
3 2018-07-01 00:00:00 2018-07-01 03:24:00
4 2018-07-02 00:00:00 2018-07-02 13:14:00
5 2018-07-03 00:00:00 2018-07-03 08:54:00
6 2018-07-02 00:00:00 2018-07-02 15:52:00
7 2018-07-03 00:00:00 2018-07-03 13:15:00
8 2018-07-08 00:00:00 2018-07-08 01:05:00
9 2018-07-07 00:00:00 2018-07-07 17:41:00
10 2018-07-04 00:00:00 2018-07-04 08:14:00
11 2018-07-05 00:00:00 2018-07-05 09:30:00
12 2018-07-10 00:00:00 2018-07-10 08:37:00
13 2018-07-05 00:00:00 2018-07-05 10:50:00
14 2018-07-14 00:00:00 2018-07-14 17:21:00
15 2018-07-14 00:00:00 2018-07-14 23:54:00
16 2018-07-20 00:00:00 2018-07-20 09:32:00
17 2018-07-21 00:00:00 2018-07-21 10:47:00
18 2018-07-10 00:00:00 2018-07-10 23:22:00
19 2018-07-12 00:00:00 2018-07-12 15:25:00
20 2018-07-12 00:00:00 2018-07-12 08:28:00
您可以看到所有日期都跨列匹配;唯一的区别是时间信息的存在。但是,当我使用 as.Date
...
将两列都转换为 date
class 时
d$date<- as.Date(d$date)
d$date_time<- as.Date(d$date_time)
# A tibble: 20 x 2
date date_time
<date> <date>
1 2018-07-07 2018-07-08
2 2018-07-08 2018-07-09
3 2018-07-01 2018-07-01
4 2018-07-02 2018-07-02
5 2018-07-03 2018-07-03
6 2018-07-02 2018-07-02
7 2018-07-03 2018-07-03
8 2018-07-08 2018-07-08
9 2018-07-07 2018-07-08
10 2018-07-04 2018-07-04
11 2018-07-05 2018-07-05
12 2018-07-10 2018-07-10
13 2018-07-05 2018-07-05
14 2018-07-14 2018-07-15
15 2018-07-14 2018-07-15
16 2018-07-20 2018-07-20
17 2018-07-21 2018-07-21
18 2018-07-10 2018-07-11
19 2018-07-12 2018-07-12
20 2018-07-12 2018-07-12
... date_time
列(第 1、2、9、14、15 和 18 行)中的几个日期已四舍五入。但是,当我使用 lubridate::as_date
进行转换时...
# A tibble: 20 x 2
date date_time
<date> <date>
1 2018-07-07 2018-07-07
2 2018-07-08 2018-07-08
3 2018-07-01 2018-07-01
4 2018-07-02 2018-07-02
5 2018-07-03 2018-07-03
6 2018-07-02 2018-07-02
7 2018-07-03 2018-07-03
8 2018-07-08 2018-07-08
9 2018-07-07 2018-07-07
10 2018-07-04 2018-07-04
11 2018-07-05 2018-07-05
12 2018-07-10 2018-07-10
13 2018-07-05 2018-07-05
14 2018-07-14 2018-07-14
15 2018-07-14 2018-07-14
16 2018-07-20 2018-07-20
17 2018-07-21 2018-07-21
18 2018-07-10 2018-07-10
19 2018-07-12 2018-07-12
20 2018-07-12 2018-07-12
...各列的日期完全匹配。我已经尝试阅读文档,但我似乎无法弄清楚为什么 as.Date
与 lubridate::as_date
的工作方式不同。事实上,as.Date
似乎在某些情况下产生了错误的转换。
有人知道这是怎么回事吗?
在 d$date
时区是 UTC
而在 d$date_time
时区默认为您的默认时区。我在美国东部时间所以这是我的:
> d$date_time
[1] "2018-07-07 23:05:00 EDT" "2018-07-09 02:25:00 EDT" "2018-07-01 06:24:00 EDT"
[4] "2018-07-02 16:14:00 EDT" "2018-07-03 11:54:00 EDT" "2018-07-02 18:52:00 EDT"
[7] "2018-07-03 16:15:00 EDT" "2018-07-08 04:05:00 EDT" "2018-07-07 20:41:00 EDT"
[10] "2018-07-04 11:14:00 EDT" "2018-07-05 12:30:00 EDT" "2018-07-10 11:37:00 EDT"
[13] "2018-07-05 13:50:00 EDT" "2018-07-14 20:21:00 EDT" "2018-07-15 02:54:00 EDT"
[16] "2018-07-20 12:32:00 EDT" "2018-07-21 13:47:00 EDT" "2018-07-11 02:22:00 EDT"
[19] "2018-07-12 18:25:00 EDT" "2018-07-12 11:28:00 EDT"
当您 运行 as.Date()
时它将 by default convert to UTC
除非您指定时区。 UTC 比 EDT 早 4 小时,因此时间在晚上 8 点之后的日子将转换为第二天,如下所示。
> as.Date(d$date_time)
[1] "2018-07-08" "2018-07-09" "2018-07-01" "2018-07-02" "2018-07-03" "2018-07-02" "2018-07-03"
[8] "2018-07-08" "2018-07-08" "2018-07-04" "2018-07-05" "2018-07-10" "2018-07-05" "2018-07-15"
[15] "2018-07-15" "2018-07-20" "2018-07-21" "2018-07-11" "2018-07-12" "2018-07-12"
Lubridate as_date()
专门解决了这个问题,甚至在其文档中提供了示例。
as_date() ignores the timezone attribute, resulting in a more
intuitive conversion (see examples)
这就是您看到差异的原因。
我有一个大型数据集,其中包含事件时间和日期的各个列。我最终创建了一个包含时间和日期的主 dttm
对象,但是当我尝试根据日期进行过滤时遇到了麻烦。这是反映我自己的示例数据集:
library(tidyverse)
d<- structure(list(date = structure(c(1530921600, 1531008000,
1530403200, 1530489600, 1530576000, 1530489600, 1530576000, 1531008000,
1530921600, 1530662400, 1530748800, 1531180800, 1530748800, 1531526400,
1531526400, 1532044800, 1532131200, 1531180800, 1531353600, 1531353600
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), date_time = structure(c(1531019100,
1531117500, 1530440640, 1530562440, 1530633240, 1530571920, 1530648900,
1531037100, 1531010460, 1530717240, 1530808200, 1531237020, 1530813000,
1531614060, 1531637640, 1532104320, 1532195220, 1531290120, 1531434300,
1531409280), class = c("POSIXct", "POSIXt"), tzone = "")), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -20L))
数据如下:
# A tibble: 20 x 2
date date_time
<dttm> <dttm>
1 2018-07-07 00:00:00 2018-07-07 20:05:00
2 2018-07-08 00:00:00 2018-07-08 23:25:00
3 2018-07-01 00:00:00 2018-07-01 03:24:00
4 2018-07-02 00:00:00 2018-07-02 13:14:00
5 2018-07-03 00:00:00 2018-07-03 08:54:00
6 2018-07-02 00:00:00 2018-07-02 15:52:00
7 2018-07-03 00:00:00 2018-07-03 13:15:00
8 2018-07-08 00:00:00 2018-07-08 01:05:00
9 2018-07-07 00:00:00 2018-07-07 17:41:00
10 2018-07-04 00:00:00 2018-07-04 08:14:00
11 2018-07-05 00:00:00 2018-07-05 09:30:00
12 2018-07-10 00:00:00 2018-07-10 08:37:00
13 2018-07-05 00:00:00 2018-07-05 10:50:00
14 2018-07-14 00:00:00 2018-07-14 17:21:00
15 2018-07-14 00:00:00 2018-07-14 23:54:00
16 2018-07-20 00:00:00 2018-07-20 09:32:00
17 2018-07-21 00:00:00 2018-07-21 10:47:00
18 2018-07-10 00:00:00 2018-07-10 23:22:00
19 2018-07-12 00:00:00 2018-07-12 15:25:00
20 2018-07-12 00:00:00 2018-07-12 08:28:00
您可以看到所有日期都跨列匹配;唯一的区别是时间信息的存在。但是,当我使用 as.Date
...
date
class 时
d$date<- as.Date(d$date)
d$date_time<- as.Date(d$date_time)
# A tibble: 20 x 2
date date_time
<date> <date>
1 2018-07-07 2018-07-08
2 2018-07-08 2018-07-09
3 2018-07-01 2018-07-01
4 2018-07-02 2018-07-02
5 2018-07-03 2018-07-03
6 2018-07-02 2018-07-02
7 2018-07-03 2018-07-03
8 2018-07-08 2018-07-08
9 2018-07-07 2018-07-08
10 2018-07-04 2018-07-04
11 2018-07-05 2018-07-05
12 2018-07-10 2018-07-10
13 2018-07-05 2018-07-05
14 2018-07-14 2018-07-15
15 2018-07-14 2018-07-15
16 2018-07-20 2018-07-20
17 2018-07-21 2018-07-21
18 2018-07-10 2018-07-11
19 2018-07-12 2018-07-12
20 2018-07-12 2018-07-12
... date_time
列(第 1、2、9、14、15 和 18 行)中的几个日期已四舍五入。但是,当我使用 lubridate::as_date
进行转换时...
# A tibble: 20 x 2
date date_time
<date> <date>
1 2018-07-07 2018-07-07
2 2018-07-08 2018-07-08
3 2018-07-01 2018-07-01
4 2018-07-02 2018-07-02
5 2018-07-03 2018-07-03
6 2018-07-02 2018-07-02
7 2018-07-03 2018-07-03
8 2018-07-08 2018-07-08
9 2018-07-07 2018-07-07
10 2018-07-04 2018-07-04
11 2018-07-05 2018-07-05
12 2018-07-10 2018-07-10
13 2018-07-05 2018-07-05
14 2018-07-14 2018-07-14
15 2018-07-14 2018-07-14
16 2018-07-20 2018-07-20
17 2018-07-21 2018-07-21
18 2018-07-10 2018-07-10
19 2018-07-12 2018-07-12
20 2018-07-12 2018-07-12
...各列的日期完全匹配。我已经尝试阅读文档,但我似乎无法弄清楚为什么 as.Date
与 lubridate::as_date
的工作方式不同。事实上,as.Date
似乎在某些情况下产生了错误的转换。
有人知道这是怎么回事吗?
在 d$date
时区是 UTC
而在 d$date_time
时区默认为您的默认时区。我在美国东部时间所以这是我的:
> d$date_time
[1] "2018-07-07 23:05:00 EDT" "2018-07-09 02:25:00 EDT" "2018-07-01 06:24:00 EDT"
[4] "2018-07-02 16:14:00 EDT" "2018-07-03 11:54:00 EDT" "2018-07-02 18:52:00 EDT"
[7] "2018-07-03 16:15:00 EDT" "2018-07-08 04:05:00 EDT" "2018-07-07 20:41:00 EDT"
[10] "2018-07-04 11:14:00 EDT" "2018-07-05 12:30:00 EDT" "2018-07-10 11:37:00 EDT"
[13] "2018-07-05 13:50:00 EDT" "2018-07-14 20:21:00 EDT" "2018-07-15 02:54:00 EDT"
[16] "2018-07-20 12:32:00 EDT" "2018-07-21 13:47:00 EDT" "2018-07-11 02:22:00 EDT"
[19] "2018-07-12 18:25:00 EDT" "2018-07-12 11:28:00 EDT"
当您 运行 as.Date()
时它将 by default convert to UTC
除非您指定时区。 UTC 比 EDT 早 4 小时,因此时间在晚上 8 点之后的日子将转换为第二天,如下所示。
> as.Date(d$date_time)
[1] "2018-07-08" "2018-07-09" "2018-07-01" "2018-07-02" "2018-07-03" "2018-07-02" "2018-07-03"
[8] "2018-07-08" "2018-07-08" "2018-07-04" "2018-07-05" "2018-07-10" "2018-07-05" "2018-07-15"
[15] "2018-07-15" "2018-07-20" "2018-07-21" "2018-07-11" "2018-07-12" "2018-07-12"
Lubridate as_date()
专门解决了这个问题,甚至在其文档中提供了示例。
as_date() ignores the timezone attribute, resulting in a more intuitive conversion (see examples)
这就是您看到差异的原因。