чому unlist () вбиває дати в R


84

Коли я видаляю список дат, він перетворює їх назад на цифри. Це нормально? Будь-яке обхідне рішення, окрім повторного застосування as.Date?

> 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

Це помилка?


2
З ?unlist: Де це можливо, елементи списку примушуються до загального режиму під час списку, і тому результат часто закінчується як вектор символів. Вектори будуть примусові до найвищого типу компонентів в ієрархії NULL <необроблений <логічний <ціле число <реальний <складний <символ <список <вираз: списки пар обробляються як списки.
Арун

6
так, я прочитав посібник .... вони вже в загальному режимі
Томас Браун

1
Я згоден, що поведінка не є нормальною. Але завжди рекомендується ознайомитися з документацією щодо функції, яку ви використовуєте.
Арун

7
@Arun Я не розумію, чому це актуально. Вектори дати є внутрішньо цілими числами, тому проблема насправді полягає в тому, що атрибути позбавляються. У документації про це явно не згадується, але немає жодного способу, щоб unlist міг зберегти атрибути загалом.
hadley

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

Відповіді:


94

do.callце зручна функція "робити щось" зі списком. У нашому випадку об’єднайте його за допомогою c. Це не рідкість cbindабо rbinddata.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,

Чому "навколо c?
Алессандро Якопсон,

3
@AlessandroJacopson цитата не є необхідною (хоча див. Файл довідки do.call), але іноді може бути корисною для функцій, які потрібно цитувати, наприклад do.call("+", as.list(c(1, 1))).
Roman Luštrik

1
ще один приємний підхід - виконати перетворення зі списку у векторний за допомогою Reduce, тобто Reduce("c",dd)
Oriol Prat

2
Дякую за код. Не відповідає на запитання, чому: чому список не вбиває дати?
dfrankow

0

Або використання 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.