Foro de debate

Trabajar con fechas en R

Trabajar con fechas en R

de Monica Ortiz Guijarro -
Número de respuestas: 14

Buenos días,

Tengo un problema con las fechas de una base de datos donde hay una fecha de inicio y otra de fin sobre un consumo de agua, pero necesito saber si por ejemplo el intervalo de fechas es: 

FECHA INICIO: 2016-01-08

FECHA FIN: 2016-03-08

Saber cuántos días pertenecen a enero en este caso serian 23, cuáles a febrero que sería 29 y cuáles a marzo que son 8. 

He conseguido crear dos intervalos con el paquete lubridate, uno donde x <- interval(FECHA INICIO, FECHA FIN), y otro intervalo donde y <- interval(inicioenero - finalenero) "teniendo en cuenta que el intervalo es entre el 01/01/2016 y 31/01/2016" y entonces comparar los dos intervalos y ver si se solapan o no con el comando: int_overlaps(x,y)

El resultado que da te dice 'TRUE' si el intervalo de fechas de mi base de datos se solapa con el intervalo del mes de enero y 'FALSE' si no se solapa. 

Sólo me faltaria saber qué días són los que pertencen a enero, en mi caso de ejemplo serian 23. 

Alguien sabe algun comando que me de este resultado? Sería de mucha ayuda,  Muchas gracias!!!

Mónica.


En respuesta a Monica Ortiz Guijarro

Re: Trabajar con fechas en R

de Manuel Muñoz Márquez -

Buenas:

¿Qué tal si calculas la diferencia entre la fecha de final de mes y la de inicio?

> d <- as.Date("2016-01-08")
> d0 <- as.Date("2016-01-31")
> d0-d
Time difference of 23 days

Un saludo

En respuesta a Manuel Muñoz Márquez

Re: Trabajar con fechas en R

de Monica Ortiz Guijarro -

Pero es que esto sólo me sirve para los días de la fecha de inicio... necesito sacar también cuántos días de consumo hay en febrero, que serían 29 y también los 8 días de marzo; de alguna manera que R me reconozca los meses que hay en mi intervalo de fechas y me saque los días exactos de consumo que hay dentro de esos meses... debajo os pongo las 6 primeras filas que he sacado de mi base de datos para que veáis mejor lo que tengo que trabajar... de la primera fila necesitaría los 21 días de mayo, los 30 de junio y los 8 de julio. 

Muchas gracias!!

2018-10-15_11-12-07-cc403aa5ec6666661e3451fb7b3a2d7e.PNG

En respuesta a Monica Ortiz Guijarro

Re: Trabajar con fechas en R

de Manuel Muñoz Márquez -

Hola Mónica:

Se me ocurre que podrías crear una columna por cada mes considerado y apuntar en dicha columna el número de días de ese mes.

Un poco más detallado:

# Vector con las fechas de inicio de los meses
fi <- c("2015-01-01", "2015-02-01")
# Vector con las fechas de fin de los meses
ff <- c("2015-01-31", "2015-02-28")
Días en mes i:
min(DAT_FI, ff[i]) - max(DAT_INI, fi[i])
Se haría un bucle en todos los meses.
Espero que te sirva.

Un saludo.
En respuesta a Manuel Muñoz Márquez

Re: Trabajar con fechas en R

de Jose Luis Cebrián -

Hola Mónica
a ver esta chapucilla para ir tirando y alguien lo mejora. De momento me sale pero de manera un poco tediosa haciendo  fila por fila.
Añado una variable llamada num_obs  y luego selecciono la observacion 1 y continuo solo con esta. No me sale hacerlas todas de golpe. Si no son muchos registros se podría hacer uno por uno pero si no hay que buscar una solución algo mejor.Espero que te ayude.

fechas
  num_obs DAT_INI_PER_CONSUM DAT_FI_PER_CONSUM VO_CONSUM_TOT dif.dates consumdiario
1       1         11/05/2015        08/07/2015         -1280        58          -22
2       2         11/05/2015        08/07/2015          1280        58           22
3       3         14/10/2015        14/12/2015            17        61            0
4       4         06/11/2015        08/01/2016             8        63            0
5       5         06/11/2015        08/01/2016            13        63            0
6       6         24/11/2015        25/01/2016             9        62            0
uno <- subset(fechas, num_obs==1); head (uno)
uno$DAT_INI_PER_CONSUM2<-as.Date(uno$DAT_INI_PER_CONSUM, format = "%d/%m/%Y"); #convierto en fecha
uno$DAT_FI_PER_CONSUM2<-as.Date(uno$DAT_FI_PER_CONSUM, format = "%d/%m/%Y")
seq1 <- seq(uno$DAT_INI_PER_CONSUM2,uno$DAT_FI_PER_CONSUM2, by="days")
seq2<-as.data.frame(seq1)
seq2$MES<-month(seq2$seq1)
seq2<-seq2%>%
	group_by(MES)%>%
	mutate(
	DIAS_MES=n_distinct(seq1),
	num_obs="1")%>%select(num_obs, MES, DIAS_MES)%>%
	distinct()
seq2$num_obs<-as.numeric(seq2$num_obs)
fechas2<-full_join(fechas, seq2)
fechas2
  num_obs DAT_INI_PER_CONSUM DAT_FI_PER_CONSUM VO_CONSUM_TOT dif.dates consumdiario MES
1       1         11/05/2015        08/07/2015         -1280        58          -22   5
2       1         11/05/2015        08/07/2015         -1280        58          -22   6
3       1         11/05/2015        08/07/2015         -1280        58          -22   7
4       2         11/05/2015        08/07/2015          1280        58           22  NA
5       3         14/10/2015        14/12/2015            17        61            0  NA
6       4         06/11/2015        08/01/2016             8        63            0  NA
7       5         06/11/2015        08/01/2016            13        63            0  NA
8       6         24/11/2015        25/01/2016             9        62            0  NA
  DIAS_MES
1       21
2       30
3        8
4       NA
5       NA
6       NA
7       NA
8       NA

En respuesta a Jose Luis Cebrián

Re: Trabajar con fechas en R

de Jose Luis Cebrián -

O mas corto usando la libreria  bizdays.
pero sigo sin conseguir hacerlo con todas las observaciones a la vez




library (bizdays)
uno2<-data.frame(Num_Obs=uno$num_obs,Dias=bizseq("2015-05-11", "2015-07-08"),               
DAT_INI_PER_CONSUM=uno$DAT_INI_PER_CONSUM,          
DAT_FI_PER_CONSUM=uno$DAT_FI_PER_CONSUM,            
VO_CONSUM_TOT=uno$VO_CONSUM_TOT,            
dif.dates=uno$dif.dates,            
consumdiari=uno$consumdiario)%>%            
mutate(         
MES=month(Dias))%>%group_by(Num_Obs, MES)%>%            
mutate(         
DIAS_MES=n_distinct(Dias))%>%as.data.frame()  

En respuesta a Jose Luis Cebrián

Re: Trabajar con fechas en R(la definitiva)

de Jose Luis Cebrián -


Por fin me salio, tuve que recurrir a data.table

library(dplyr)

library(data.table)

fechas1<-setDT(fechas)[,.(dias=seq(DAT_INI_PER_CONSUM2, DAT_FI_PER_CONSUM2, by='days')),

             by=num_obs] 

fechas2<-merge(fechas, fechas1); 

fechas3<-fechas2%>%

mutate(         

MES=month(dias))%>%

group_by(num_obs, MES)%>%            

mutate(         

DIAS_MES=n_distinct(dias))%>%

as.data.frame()

head (fechas3)

En respuesta a Jose Luis Cebrián

Re: Trabajar con fechas en R(la definitiva)

de Monica Ortiz Guijarro -

Muchas gracias!! he conseguido hacerlo para una observación también! Pero al poner el comando como tu última respuesta que en principio debería de hacérmelo para todos los intervalos de fechas no? me sale este error:  "Error in seq.default(DAT_INI_PER_CONSUM, DAT_FI_PER_CONSUM) : 

  'from' must be of length 1"

Es que pones dias=seq(DAT_INI_PER_CONSUM2?? El CONSUM2 que significa? pertenece sólo a la primera fila del data.table? Yo he puesto dias=seq(DAT_INI_PER_CONSUM, tal cual teniendo en cuenta todas las filas... quizá lo estoy haciendo mal... y sólo hay que poner los días del primer intervalo de fechas de la primera fila... 

Pero mi base de datos original es de millones de filas...lo tendría que hacer para todas las filas a la vez, sino es una locura hacerlo uno por uno.

En respuesta a Monica Ortiz Guijarro

Re: Trabajar con fechas en R(la definitiva)

de Jose Luis Cebrián -


Buenas.

A mi me sale para todos las filas, entiendo que si no es así no sirve de mucho.

A veces me da ese error que tu dices pero aún asi no pasa nada (o sea que me genera "fechas1).

He creado las variables  DAT_INI_PER_CONSUM2 y DAT_FI_PER_CONSUM2 

en formato fecha porque las otras me salian como factores.

Como ves en head(fechas3) y tail(fechas3) sale para todas las filas.

Confirmame que te sale o que no te sale 

Saludos


 fechas <- read.csv("~/fechas.txt", sep="")
> head (fechas)
  num_obs DAT_INI_PER_CONSUM DAT_FI_PER_CONSUM VO_CONSUM_TOT dif.dates
1       1         11/05/2015        08/07/2015         -1280        58
2       2         11/05/2015        08/07/2015          1280        58
3       3         14/10/2015        14/12/2015            17        61
4       4         06/11/2015        08/01/2016             8        63
5       5         06/11/2015        08/01/2016            13        63
6       6         24/11/2015        25/01/2016             9        62
  consumdiario
1          -22
2           22
3            0
4            0
5            0
6            0
> fechas$DAT_INI_PER_CONSUM2<-as.Date(fechas$DAT_INI_PER_CONSUM, format="%d/%m/%Y")
> fechas$DAT_FI_PER_CONSUM2<-as.Date(fechas$DAT_FI_PER_CONSUM, format="%d/%m/%Y")
> fechas1<-setDT(fechas)[,.(dias=seq(DAT_INI_PER_CONSUM2, DAT_FI_PER_CONSUM2, by='days')),      
                         by=num_obs]
Error in .(dias = seq(DAT_INI_PER_CONSUM2, DAT_FI_PER_CONSUM2, by = "days")): could not find function "."
> head (fechas1)
   num_obs       dias
1:       1 2015-05-11
2:       1 2015-05-12
3:       1 2015-05-13
4:       1 2015-05-14
5:       1 2015-05-15
6:       1 2015-05-16
> tail(fechas1)
   num_obs       dias
1:       6 2016-01-20
2:       6 2016-01-21
3:       6 2016-01-22
4:       6 2016-01-23
5:       6 2016-01-24
6:       6 2016-01-25
> fechas2<-merge(fechas, fechas1); head (fechas2)
   num_obs DAT_INI_PER_CONSUM DAT_FI_PER_CONSUM VO_CONSUM_TOT dif.dates
1:       1         11/05/2015        08/07/2015         -1280        58
2:       1         11/05/2015        08/07/2015         -1280        58
3:       1         11/05/2015        08/07/2015         -1280        58
4:       1         11/05/2015        08/07/2015         -1280        58
5:       1         11/05/2015        08/07/2015         -1280        58
6:       1         11/05/2015        08/07/2015         -1280        58
   consumdiario DAT_INI_PER_CONSUM2 DAT_FI_PER_CONSUM2       dias
1:          -22          2015-05-11         2015-07-08 2015-05-11
2:          -22          2015-05-11         2015-07-08 2015-05-12
3:          -22          2015-05-11         2015-07-08 2015-05-13
4:          -22          2015-05-11         2015-07-08 2015-05-14
5:          -22          2015-05-11         2015-07-08 2015-05-15
6:          -22          2015-05-11         2015-07-08 2015-05-16
> fechas3<-fechas2%>%
+   mutate(         
+     MES=month(dias))%>%
+   group_by(num_obs, MES)%>%            
+   mutate(         
+     DIAS_MES=n_distinct(dias))%>%
+   as.data.frame()
> head(fechas3)
  num_obs DAT_INI_PER_CONSUM DAT_FI_PER_CONSUM VO_CONSUM_TOT dif.dates
1       1         11/05/2015        08/07/2015         -1280        58
2       1         11/05/2015        08/07/2015         -1280        58
3       1         11/05/2015        08/07/2015         -1280        58
4       1         11/05/2015        08/07/2015         -1280        58
5       1         11/05/2015        08/07/2015         -1280        58
6       1         11/05/2015        08/07/2015         -1280        58
  consumdiario DAT_INI_PER_CONSUM2 DAT_FI_PER_CONSUM2       dias MES
1          -22          2015-05-11         2015-07-08 2015-05-11   5
2          -22          2015-05-11         2015-07-08 2015-05-12   5
3          -22          2015-05-11         2015-07-08 2015-05-13   5
4          -22          2015-05-11         2015-07-08 2015-05-14   5
5          -22          2015-05-11         2015-07-08 2015-05-15   5
6          -22          2015-05-11         2015-07-08 2015-05-16   5
  DIAS_MES
1       21
2       21
3       21
4       21
5       21
6       21
> tail (fechas3)
    num_obs DAT_INI_PER_CONSUM DAT_FI_PER_CONSUM VO_CONSUM_TOT dif.dates
366       6         24/11/2015        25/01/2016             9        62
367       6         24/11/2015        25/01/2016             9        62
368       6         24/11/2015        25/01/2016             9        62
369       6         24/11/2015        25/01/2016             9        62
370       6         24/11/2015        25/01/2016             9        62
371       6         24/11/2015        25/01/2016             9        62
    consumdiario DAT_INI_PER_CONSUM2 DAT_FI_PER_CONSUM2       dias MES
366            0          2015-11-24         2016-01-25 2016-01-20   1
367            0          2015-11-24         2016-01-25 2016-01-21   1
368            0          2015-11-24         2016-01-25 2016-01-22   1
369            0          2015-11-24         2016-01-25 2016-01-23   1
370            0          2015-11-24         2016-01-25 2016-01-24   1
371            0          2015-11-24         2016-01-25 2016-01-25   1
    DIAS_MES
366       25
367       25
368       25
369       25
370       25
371       25

En respuesta a Jose Luis Cebrián

Re: Trabajar con fechas en R(la definitiva)

de Monica Ortiz Guijarro -

Vale ahora sí me sale igual que a ti, muchas gracias por la ayuda!! me viene genial para hacer un estudio de distribución del consumo del agua que tengo en mente para mi trabajo. La verdad que R te soluciona mucho la vida. 

Saludos!

En respuesta a Jose Luis Cebrián

Re: Trabajar con fechas en R(la definitiva)

de Ana Bonilla Ruiz -

Buenas tardes, estoy usando lo que respondió en este foro, pero tengo el problema de que la fecha de inicio y final coinciden, entoces , me da este error:

Error in seq.int(0, to0 -from , by) :wrong in 'by' argument.

¿Cómo puedo solventarlo?

Un saludo, Ana.

En respuesta a Ana Bonilla Ruiz

Re: Trabajar con fechas en R(la definitiva)

de Manuel Muñoz Márquez -

Buenas Ana:

Las fechas de inicio y fin no pueden coincidir, pues las de inicio y fin de cada periodo.

Si pones un ejemplo de lo que intentas y de tu código es más fácil ayudarte.

Un saludo.

En respuesta a Monica Ortiz Guijarro

Re: Trabajar con fechas en R

de javier muro -

Hola Mónica,

Puedes crear una nueva variable MES (datos$MES<-month(FECHA) y así puedes contar el número de veces que te sale cada uno de los componentes del MES.

Saludos