Tibbles拒绝了Rubridate的持续时间和期间对象

时间:2018-01-04 01:09:00

标签: r lubridate tibble

有效的代码:durationperiod个对象

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

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

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

无效的代码:duration中的periodtibble个对象

但是,当我尝试使用tibbleduration对象创建period时,我会收到无法提供信息的错误消息。

> 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.

有效的代码:duration中的perioddata.frame个对象

tibble::tibble替换base::data.frame

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

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

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

使用tibble::as_tibble将这些data.frame强制转换为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 --> list_to_tibble --> 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的问题有相同的原因。

套餐版

  • Tibble:1.4.1
  • Lubridate:1.7.1
  • R:3.4.3

1 个答案:

答案 0 :(得分:3)

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