Почему unlist () убивает даты в R?


87

Когда я вычеркиваю список дат, он снова превращает их в числа. Это нормально? Любой обходной путь, кроме повторной подачи заявки как Дата?

> dd <- as.Date(c("2013-01-01", "2013-02-01", "2013-03-01"))
> class(dd)
[1] "Date"
> unlist(dd)
[1] "2013-01-01" "2013-02-01" "2013-03-01"
> list(dd)
[[1]]
[1] "2013-01-01" "2013-02-01" "2013-03-01"

> unlist(list(dd))
[1] 15706 15737 15765

Это ошибка?


3
Откуда ?unlist: там, где это возможно, элементы списка переводятся в общий режим во время исключения из списка, поэтому результат часто оказывается вектором символов. Векторы будут приведены к наивысшему типу компонентов в иерархии NULL <raw <logic <integer <real <complex <character <list <expression: pairlists обрабатываются как списки.
Arun

6
да, я прочитал руководство .... они уже в обычном режиме
Thomas Browne

1
Я согласен, что поведение ненормальное. Но всегда рекомендуется читать документацию по используемой вами функции.
Arun

7
@ Арун, я не понимаю, почему это актуально. Векторы дат являются внутренне целыми числами, поэтому проблема в том, что атрибуты удалены. В документации это не упоминается явно, но unlist не может сохранить атрибуты в целом.
Hadley

1
@Arun да, потому что unlistвозвращает без изменений входные данные, не входящие в список. Мне это совсем не кажется размытым, но в документации должно быть указано, что происходит с атрибутами.
hadley

Ответы:


97

do.call- удобная функция, позволяющая «что-то делать» со списком. В нашем случае объедините его с помощью c. Это не редкость для cbindилиrbind data.frames из списка в один большой data.frame.

Фактически мы собираем элементы ddсписка. Это было бы аналогично c(dd[[1]], dd[[2]]). Обратите внимание, что это cможет быть функция или символ.

> dd <- list(dd, dd)
> (d <- do.call("c", dd))
[1] "2013-01-01" "2013-02-01" "2013-03-01" "2013-01-01" "2013-02-01" "2013-03-01"
> class(d) # proof that class is still Date
[1] "Date"

7
Этот ответ был бы значительно улучшен, если бы вы могли добавить немного подробностей, объясняющих, что вы делаете, чтобы другие сочли его более читаемым позже.
Dinre

3
@AlessandroJacopson цитата не обязательна (хотя см. Файл справки do.call), но иногда может быть полезна для функций, которые необходимо цитировать, например do.call("+", as.list(c(1, 1))).
Роман Луштрик

1
еще один хороший подход - выполнить преобразование из списка в вектор с помощью Reduce, то есть Reduce("c",dd)
Oriol Prat

1
@OriolPrat, который вызывает Reducen-1 раз, где n - длина списка. Это будет ужасно работать с большими векторами, аналогично (фактически, идентично) тому, почему итеративное построение списка / вектора является плохим исполнителем.
r2evans

2
Спасибо за код. Не отвечает на вопрос, хотя: почему unlist kill date?
dfrankow

1

Или используйте purrr для сглаживания списка дат до типов с сохранением вектора:

list(as.Date(c("2013-01-01", "2013-02-01", "2013-03-01"))) %>% purrr::reduce(c)

приводит к

[1] "2013-01-01" "2013-02-01" "2013-03-01"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.