por qué unlist () mata las fechas en R

84

Cuando elimino una lista de fechas, las vuelve a convertir en números. ¿Eso es normal? ¿Alguna solución alternativa que no sea volver a aplicar como fecha?

> 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

¿Es esto un error?

Thomas Browne
fuente
2
Desde ?unlist: cuando es posible, los elementos de la lista se fuerzan a un modo común durante la eliminación de la lista, por lo que el resultado a menudo termina como un vector de caracteres. Los vectores serán coaccionados al tipo más alto de los componentes en la jerarquía NULL <raw <lógico <entero <real <complejo <carácter <lista <expresión: los pares se tratan como listas.
Arun
6
sí, leí el manual ... ya están en un modo común
Thomas Browne
1
Estoy de acuerdo en que el comportamiento no es normal. Pero siempre se recomienda leer la documentación de la función que estás usando.
Arun
7
@Arun No veo por qué eso es relevante. Los vectores de fecha son internamente enteros, por lo que el problema es que los atributos se eliminan. La documentación no menciona esto explícitamente, pero no hay forma de que unlist pueda conservar los atributos en general.
hadley
1
@Arun sí, porque unlistdevuelve entradas que no están en la lista sin cambios. No me parece nada borroso, pero la documentación debería mencionar lo que sucede con los atributos.
hadley

Respuestas:

94

do.calles una función útil para "hacer algo" con una lista. En nuestro caso, concatenarlo usando c. No es raro que cbindo rbinddata.frames de una lista en un solo big data.frame.

Lo que estamos haciendo aquí es en realidad concatenar elementos de la ddlista. Esto sería análogo a c(dd[[1]], dd[[2]]). Tenga en cuenta que cse puede suministrar como función o como carácter.

> 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"
Roman Luštrik
fuente
7
Esta respuesta se mejoraría mucho si pudiera agregar un poco más de detalle explicando lo que está haciendo, para que otros la encuentren más legible más adelante.
Dinre
¿Por qué "alrededor c?
Alessandro Jacopson
3
@AlessandroJacopson la cita no es necesaria (aunque vea el archivo de ayuda de do.call) pero a veces puede ser útil para funciones que necesitan ser citadas, por ejemplo do.call("+", as.list(c(1, 1))).
Roman Luštrik
1
otro buen enfoque es realizar la conversión de lista a vector con Reduce, es decir Reduce("c",dd)
Oriol Prat
2
Gracias por el codigo. No responde la pregunta, aunque: ¿por qué no enumerar las fechas de muerte?
dfrankow
0

O usando purrr para aplanar una lista de fechas a un vector que conserva tipos:

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

resultados en

[1] "2013-01-01" "2013-02-01" "2013-03-01"
Salim B
fuente