Tibbles 拒绝 lubridate 的持续时间和周期对象

Posted

技术标签:

【中文标题】Tibbles 拒绝 lubridate 的持续时间和周期对象【英文标题】:Tibbles reject lubridate's duration and period objects 【发布时间】:2018-06-13 17:12:14 【问题描述】:

有效的代码:durationperiod 对象

以下代码分别成功生成duration对象和period对象。

> lubridate::as.duration(1)
[1] "1s"

> lubridate::seconds(1)
[1] "1S"

不起作用的代码:tibbles 中的 durationperiod 对象

但是,当我尝试使用 durationperiod 对象创建 tibbles 时,我收到了无意义的错误消息。

> tibble::tibble(y = lubridate::as.duration(1))
Error: Incompatible duration classes (Duration, numeric). Please coerce with `as.duration`.

> tibble::tibble(y = lubridate::seconds(1))
Error in x < 0 : cannot compare Period to Duration:
coerce with 'as.numeric' first.

有效的代码:data.frames 中的 durationperiod 对象

base::data.frame 替换tibble::tibble 有效。

> data.frame(y = lubridate::as.duration(1))
   y
1 1s

> data.frame(y = lubridate::seconds(1))
   y
1 1S

无效的代码 - 将这些 data.frames 强制转换为 tibbles

使用tibble::as_tibble 将这些data.frames 强制转换为tibbles 会产生与以前相同的错误。

> tibble::as_tibble(data.frame(y = lubridate::as.duration(1)))
Error: Incompatible duration classes (Duration, numeric). Please coerce with `as.duration`.

> tibble::as_tibble(data.frame(y = lubridate::seconds(1)))
Error in x < 0 : cannot compare Period to Duration:
coerce with 'as.numeric' first.

可能的解释

Hadley 在这个 Github 问题 - https://github.com/tidyverse/tibble/issues/326 中提到了一些关于 S4 列的内容,其中包括 as.durationas.period。没有特别提到不兼容。

挖掘源代码,我发现以下依赖链给出了相同的错误消息:as_tibble.data.frame --&gt; list_to_tibble --&gt; new_tibble

tibble:::list_to_tibble 中,传递给tibble::new_tibble 的唯一参数是x。因此,subclass 被赋予了默认值NULL,而tibble::new_tibble 的倒数第二行变成了

class(x) <- c("tbl_df", "tbl", "data.frame")

对象具有结构,但尝试直接调用它们会产生错误。

> x <- data.frame(y = lubridate::as.duration(1))
> class(x) <- c("tbl_df", "tbl", "data.frame")
> str(x)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   1 obs. of  1 variable:
 $ x:Formal class 'Duration' [package "lubridate"] with 1 slot
  .. ..@ .Data: num 1
> x
Error: Incompatible duration classes (Duration, numeric). Please coerce with `as.duration`.

> x <- data.frame(y = lubridate::seconds(1))
> class(x) <- c("tbl_df", "tbl", "data.frame")
> str(x)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   1 obs. of  1 variable:
 $ y:Formal class 'Period' [package "lubridate"] with 6 slots
  .. ..@ .Data : num 1
  .. ..@ year  : num 0
  .. ..@ month : num 0
  .. ..@ day   : num 0
  .. ..@ hour  : num 0
  .. ..@ minute: num 0
> x 
Error in x < 0 : cannot compare Period to Duration:
coerce with 'as.numeric' first.

因此,似乎将data.frame x 的类分配给向量c("tbl_df", "tbl", "data.frame") 会导致R 尝试以引发错误的方式强制x

此外,鉴于tibble::tibble 也调用as_tibble(虽然不在data.frame 上),我会冒险猜测我与tibble::tibble 的问题有相同的原因。

软件包版本

小标题:1.4.1 润滑:1.7.1 R:3.4.3

【问题讨论】:

另一个 R 用户遇到了同样的问题并在 Github 上打开了一个问题:github.com/tidyverse/tibble/issues/358。暂时不要回答这个问题,因为哈德利还没有回答这个问题。 【参考方案1】:

此问题现已从支柱 v.1.2.1 (https://github.com/r-lib/pillar/issues/88) 开始解决。

【讨论】:

以上是关于Tibbles 拒绝 lubridate 的持续时间和周期对象的主要内容,如果未能解决你的问题,请参考以下文章

仅当每月少于 10 天是 NA 时,如何使用 dplyr 和 lubridate 每月汇总每日数据?

R 用 lubridate 在 DST 上添加月份会产生意想不到的结果

R:lubridate 的 dst() 没有按预期工作

lubridate - 从十进制小时中获取小时和分钟

R Lubridate dmy 输出格式

as.Date函数将字符串转化为日期as.Date指定format的格式lubridate包日期格式转换系统日期系统时间日期比较日期差lubridate包获取关系日期的详细信息