Tibbles отклоняют объекты продолжительности и периода lubridate

Работающий код: объекты duration и period

Следующий код успешно создает объект duration и объект period соответственно.

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

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

Неработающий код: объекты duration и period в tibbles

Однако, когда я пытаюсь создать tibbles с помощью объекта duration или 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 и period в data.frames

Замена 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.

Возможное объяснение

Хэдли упоминает кое-что в этом выпуске Github - https://github.com/tidyverse/tibble/issues/326 - о столбцах S4, которые включают as.duration и as.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 имеют ту же причину.

Версии пакета

  • Таблица: 1.4.1
  • Lubridate: 1.7.1
  • R: 3.4.3

person Community    schedule 04.01.2018    source источник
comment
Другой пользователь R столкнулся с той же проблемой и открыл проблему на Github: github.com/tidyverse/tibble/ вопросов / 358. Пока оставляем вопрос без ответа, так как Хэдли еще не ответила на него.   -  person    schedule 14.01.2018


Ответы (1)


Эта проблема теперь решена в версии 1.2.1 (https://github.com/r-lib/pillar/issues/88).

person Community    schedule 12.03.2018