Dlaczego unlist () zabija daty w R?


87

Kiedy wyłączam listę dat, zamienia je z powrotem w liczby. Czy to normalne? Jakieś obejście inne niż ponowne zgłoszenie jako data?

> 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

Czy to błąd?


3
Od ?unlist: Tam, gdzie to możliwe, elementy listy są wymuszane do wspólnego trybu podczas niepublicznej listy, więc wynik często kończy się jako wektor znakowy. Wektory zostaną przekształcone do najwyższego typu komponentów w hierarchii NULL <surowe <logiczne <całkowite <rzeczywiste <złożone <znak <lista <wyrażenie: listy par są traktowane jak listy.
Arun

6
tak, przeczytałem instrukcję… są już w trybie wspólnym
Thomas Browne

1
Zgadzam się, że zachowanie nie jest normalne. Ale zawsze zaleca się przeczytanie dokumentacji używanej funkcji.
Arun

7
@Arun Nie rozumiem, dlaczego to ma znaczenie. Wektory dat są wewnętrznie liczbami całkowitymi, więc problem polega na tym, że atrybuty są usuwane. Dokumentacja nie wspomina o tym wprost, ale nie ma możliwości, aby pozycja niepubliczna mogła ogólnie zachować atrybuty.
hadley

1
@Arun tak, ponieważ unlistzwraca niezmienione dane wejściowe spoza listy. Nie wydaje mi się to wcale niewyraźne, ale dokumentacja powinna wspomnieć o tym, co dzieje się z atrybutami.
hadley

Odpowiedzi:


98

do.callto przydatna funkcja do „zrobienia czegoś” z listą. W naszym przypadku połącz go za pomocą c. To nie jest rzadkością cbindlub rbinddata.frames z listy w jeden wielki data.frame.

To, co tutaj robimy, to konkatenacja elementów ddlisty. Byłoby to analogiczne do c(dd[[1]], dd[[2]]). Zauważ, że cmoże być dostarczone jako funkcja lub jako znak.

> 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
Ta odpowiedź byłaby znacznie lepsza, gdybyś mógł dodać trochę więcej szczegółów wyjaśniających, co robisz, aby inni uznali ją później za bardziej czytelną.
Dinre

3
@AlessandroJacopson cytat nie jest konieczny (chociaż zobacz plik pomocy do.call), ale czasami może być przydatny w przypadku funkcji, które wymagają cytowania, np do.call("+", as.list(c(1, 1))).
Roman Luštrik,

1
innym fajnym podejściem jest wykonanie konwersji z listy na wektor Reducenp. Reduce("c",dd)
Oriol Prat

1
@OriolPrat, który wywołuje Reducen-1 razy, gdzie n jest długością listy. Będzie to działać okropnie z większymi wektorami, analogicznie (właściwie identycznie) do tego, dlaczego iteracyjne tworzenie listy / wektorów jest słabe.
r2evans

2
Dzięki za kod. Nie odpowiada jednak na pytanie: dlaczego ukrywanie dat zabójstw na liście?
dfrankow

1

Lub używając mruczenia, aby spłaszczyć listę dat do wektorów zachowujących typy:

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

prowadzi do

[1] "2013-01-01" "2013-02-01" "2013-03-01"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.