2011-11-30 19 views
31

utilizo lubridate y pensé que esto sería tan fácilGenerar una secuencia del último día del mes durante dos años

ymd("2010-01-31")+months(0:23) 

Pero mira lo que se obtiene. ¡Está todo en mal estado!

[1] "2010-01-31 UTC" "2010-03-03 UTC" "2010-03-31 UTC" "2010-05-01 UTC" "2010-05-31 UTC" "2010-07-01 UTC" "2010-07-31 UTC" "2010-08-31 UTC" "2010-10-01 UTC" 
[10] "2010-10-31 UTC" "2010-12-01 UTC" "2010-12-31 UTC" "2011-01-31 UTC" "2011-03-03 UTC" "2011-03-31 UTC" "2011-05-01 UTC" "2011-05-31 UTC" "2011-07-01 UTC" 
[19] "2011-07-31 UTC" "2011-08-31 UTC" "2011-10-01 UTC" "2011-10-31 UTC" "2011-12-01 UTC" "2011-12-31 UTC" 

Luego leo cómo lubridate atiende a fenómenos como el intervalo, la duración y el período. Entonces, bien, me doy cuenta de que un mes es realmente el número de días definidos por (365 * 4 + 1)/48 = 30.438 días. Así que traté de hacerlo inteligente y reescribirlo como

ymd("2010-01-31")+ as.period(months(0:23)) 

Pero eso acaba de dar un error.

Error in as.period.default(months(0:23)) : 
    (list) object cannot be coerced to type 'double' 

Respuesta

70

Sí, encontró el truco correcto: retroceder un día desde el primero de el próximo mes.

Aquí es como una sola línea en la base R:

R> seq(as.Date("2010-02-01"), length=24, by="1 month") - 1 
[1] "2010-01-31" "2010-02-28" "2010-03-31" "2010-04-30" "2010-05-31" 
[6] "2010-06-30" "2010-07-31" "2010-08-31" "2010-09-30" "2010-10-31" 
[11] "2010-11-30" "2010-12-31" "2011-01-31" "2011-02-28" "2011-03-31" 
[16] "2011-04-30" "2011-05-31" "2011-06-30" "2011-07-31" "2011-08-31" 
[21] "2011-09-30" "2011-10-31" "2011-11-30" "2011-12-31" 
R> 

Así que no hay necesidad de lubridate la que (mientras que ser un paquete muy bien) no es necesario para la tarea simple como esto. Además, su sobrecarga de funciones base existentes todavía me parece algo peligroso ...

11

Es sorprendente cómo escribir a máquina una pregunta concentra la energía creativa. Creo que resolví la respuesta. También puedo publicarlo aquí para la próxima alma pobre que se encuentra perdiendo el tiempo.

ymd("2010-02-01")+ months(0:23)-days(1) 

basta con especificar el primer día del siguiente mes y generar una secuencia de eso, pero restan 1 día de ella para conseguir el último día del mes anterior.

[1] "2010-01-31 UTC" "2010-02-28 UTC" "2010-03-31 UTC" "2010-04-30 UTC" "2010-05-31 UTC" "2010-06-30 UTC" "2010-07-31 UTC" "2010-08-31 UTC" "2010-09-30 UTC" 
[10] "2010-10-31 UTC" "2010-11-30 UTC" "2010-12-31 UTC" "2011-01-31 UTC" "2011-02-28 UTC" "2011-03-31 UTC" "2011-04-30 UTC" "2011-05-31 UTC" "2011-06-30 UTC" 
[19] "2011-07-31 UTC" "2011-08-31 UTC" "2011-09-30 UTC" "2011-10-31 UTC" "2011-11-30 UTC" "2011-12-31 UTC" 

Por cierto, ¿cómo me deshago de las molestas designaciones "UTC". Las zonas horarias son un salvavidas cuando se necesitan. El resto del tiempo son una molestia.

+4

use 'strftime (date)' para deshacerse de la zona horaria. entonces 'strftime ('2010-10-31 UTC')' te daría '2010-10-31'. – Ramnath

+0

¿Puedes aceptar tu respuesta también para la próxima pobre alma? –

+0

@SachaEpskamp: Stackoverflow solo me permitirá aceptar mi respuesta después de dos días. Supongo que es bastante inteligente. Puede haber otra solución que sea más elegante. – Farrel

Cuestiones relacionadas