Split-Apply-Combine-Parte 2

Parte 2.-Procesando los datos y analizando otras posibles relaciones.

En la primera parte solo puse algunos ejemplos de gráficas que se pueden generar de manera directa de los datos sin hacer ningún procesamientos sobre la información.

Existen varias librerías para procesar datos en R project, las que aparecen en mayor cantidad de referencias son reshape2, dplyr y data.table. Para realizar un procesa SAC en los datos, no basta con solo revisar las variables de manera directa, es recomendable hacer un poco de procesamiento de los datos para realizar una exploración más sutil sobre la información.

En la entrada “Algo de procesamiento de datos” compartí algunos ejemplos sencillos del uso de las tres librerías de R y sobre el procesamiento de datos en Python con Pandas. Por lo cual no explico todos los detalles sobre las funciones, para más detalles se puede revisar esa entrada o las referencias que dejé en esa entrada.

Algo más

Usando dplyr y reshape2, se pueden explorar otro tipo de relaciones entre los datos. Ejemplo, la información de los vuelos cuenta con 16 variables de las cuales 3 de ellas indican el año, mes y día. Estas tres variables pueden permitir construir la variable de fecha la cual nos permite preguntarnos sobre la información desde un punto de vista de series de tiempo.

Una serie de tiempo es analizar el comportamiento de un indicador con respecto a la variación del tiempo, esto si bien no es claro lo muestro en el ejemplo. Formalmente es un proceso estocástico que tienen un parámetro t de tiempo.

La intención con ciertas transformaciones y agrupamientos de los datos es permitir explorar la información de manera diferente a lo que podemos hacer directamente desde la tabla de datos.

Tratamiento 1

#Se cargan los datos y las librerías requeridas para el análisis
#Se cargan las librerías
library(nycflights13)
library(dplyr)
library(reshape2)
library(ggplot2)

#Revisión de los datos
data("flights")
dim(flights)
#[1] 336776 16
#missing value
#Se eliminan las filas sin datos completos

sum(is.na(flights))
#[1] 60593
flights2=na.omit(flights)
head(flights2,10)
str(flights2)
dim(flights2)
#[1] 327346 16

#Agrupamos por fechas y aeropuerto de origen
a1<-flights2%>%
 group_by(year,month,day,origin)%>%
 summarise(count=n(),retrasos=sum(dep_delay+arr_delay),distancia=mean(distance))

#Se revisan el tipo de datos con los siguientes comenados
head(a1)
dim(a1)
#[1] 1095 7
str(a1)

#Agrego una variable para la fecha

a2=mutate(a1,fechas=as.Date(paste(month,day,year,sep="/"),"%m/%d/%Y"))
dim(a2)
#1095 8
str(a2)

head(a2)
#Source: local data frame [6 x 8]
#Groups: year, month, day

 #year month day origin count retrasos distancia fechas
#1 2013 1 1 EWR 300 11455 1039.8033 2013-01-01
#2 2013 1 1 JFK 295 5944 1297.1424 2013-01-01
#3 2013 1 1 LGA 236 2617 843.6695 2013-01-01
#4 2013 1 2 EWR 341 17242 1010.3900 2013-01-02
#5 2013 1 2 JFK 317 3641 1281.3502 2013-01-02
#6 2013 1 2 LGA 270 3589 841.9519 2013-01-02

Lo que se hizo con el código anterior fue construir desde los datos originales un data.frame o una tabla de datos con la información ordenada de otro modo y lista para poder explorarla como serie de tiempo. Lo que se hizo fue contabilizar la cantidad de vuelos por día, sumar los minutos de retraso al despegar y al arribar y calcular la distancia media recorrida por día.

Se pueden hacer algunas cosas con esta información, primero visualizar el comportamiento de los datos por cada aeropuerto de origen y después explorar si existe alguna relación entre las 3 series de tiempo.

 #Serie de tiempo 1
ggplot(a2,aes(x=fechas,y=count))+geom_line(aes(colour=factor(origin)))+scale_x_date()+facet_grid(.~origin)+geom_smooth(col="black")+
 ggtitle("Número de vuelos por año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Cantidad de vuelo")+xlab("Fecha de Vuelos")

La gráfica es la siguiente:

Serie_T1

#Serie de tiempo 2
ggplot(a2,aes(x=fechas,y=retrasos))+geom_line(aes(colour=factor(origin)))+scale_x_date()+facet_grid(.~origin)+geom_smooth(col="black")+
 ggtitle("Minutos de retrasos por vuelo en el año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Minutos de retraso")+xlab("Fecha de Vuelos")

La gráfica es la siguiente:

Serie_T2

#Serie de tiempo 3
ggplot(a2,aes(x=fechas,y=distancia))+geom_line(aes(colour=factor(origin)))+scale_x_date()+facet_grid(.~origin)+geom_smooth(col="black")+
 ggtitle("Media de la distancia de vuelo por año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Media de la distancia de vuelo")+xlab("Fecha de Vuelos")

La gráfica es la siguiente:

Serie_T3

Revisando el “cruce” entre la cantidad de vuelos, la distancia media y el total de minutos de retraso se obtienen las siguientes gráficas.

#Cruce 1
ggplot(a2,aes(count,retrasos))+geom_point(aes(colour=origin))+facet_grid(.~origin)+geom_smooth(col="black")
 ggtitle("Scatter plot de Cantidad de vuelos vs retrasos ")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Cantidad de Vuelos")+xlab("Retrasos por Aeropuertos")

La gráfica que se obtiene es la siguiente:

SC1

#Cruce 2
ggplot(a2,aes(count, distancia))+geom_point(aes(colour=origin))+facet_grid(.~origin)+geom_smooth(col="black")+
 ggtitle("Scatter plot de cantidad de vuelos vs distancia media por año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Cantidad de Vuelos")+xlab("Distancia media por Aeropuertos")

La gráfica es la siguiente:

SP2

#Cruce 3
ggplot(a2,aes(y=distancia,x=retrasos))+geom_point(aes(colour=origin))+facet_grid(.~origin)+geom_smooth(col="black")+
 ggtitle("Scatter plot entre la distancia media y los retrasos por año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Media de la distancia de vuelo")+xlab("Retrasos por Aeropuertos")

La gráfica es la siguiente:

SC3

El único fin de las 6 gráficas anteriores es tratar de detectar alguna información o relación entre la información que con los datos originales no sea visible.

Analizando someramente las gráficas se puede observar en la primera gráfica que en los dos primeros aeropuertos el comportamiento es “similar”, ya que incremente la cantidad de vuelos de primavera hasta verano y posteriormente decrece cuando el año llega al invierno.La diferencia con el aeropuerto LGA que muestra un incremento conforme el año se acerca al invierno.

En la segunda gráfica se aprecia que para los 3 aeropuerto los retrasos incrementan en verano, con un poco de cuidado se aprecia que entre los meses de Febrero e inicio de Marzo se muestra un pico en los retrasos, el cual puede deberse a la temporada de cierre de nevadas.

El tercero resulta claro cual aeropuerto es requerido para vuelos con distancias mayores, JFK, y cual parece para vuelos cercanos. Revisando esto con la gráfica 1 se puede tener sospechas de que el incremento en la cantidad de vuelos en el aeropuerto LGA al cierre de año está relacionado con que se realizan vuelos cortos, lo cual puede estar relacionado con los festejos de cierre de año y periodos vacacionales.

Las últimas 3 gráficas son más sutiles, ya que se requeriría revisar la correlación y el coeficiente de información mutua para explorar si existe alguna relación interesante en los cruces. Por ejemplo la gráfica 5 muestra ciertas relaciones lineales negativa entre la cantidad de vuelos y la media de distancia en el aeropuerto LGA, pero en los otros dos no se muestra que exista dicha relación.

La gráfica 4 y 6 no muestran relaciones lineales, pero es posible que si tengan relaciones no lineales para lo cual se podría usar el índice de información mutual para tener algún indicio.

 Lo que debe de estar claro es que con unas agrupaciones y transformaciones se pudo explorar la información desde otra perspectiva y permite pensar en hacer cierto tipo de análisis, ejemplo las tres primeras gráficas permiten incitar en realizar un análisis de series de tiempo de los datos y con ellos crear un modelo predictivo de la cantidad de vuelos por mes o el comportamiento de los retrasos por mes.

Tratamiento 2

El siguiente ejemplo son dos partes, la primera es elegir el número de cola del avión con mayor cantidad de vuelos realizados y analizar sus comportamiento con respecto al año. Por último tomo un ejemplo que resulta similar al presentado en la página de referencia de la librería dplyr, con algunas ligeras variaciones.

Para elegir la cola de avión con mayor cantidad de vuelos, es decir; la variable tailnum agrupo la información con respecto a esa variable y resumo la información para conocer el registro con mayor número de vuelos.

#Agrupación
plane1<-flights2%>%
   group_by(tailnum,origin)%>%
   summarise(count=n(),retrasos=sum(arr_delay),med_distancia=mean(distance))

head(plane1)
#Source: local data frame [6 x 5]
#Groups: tailnum

 #tailnum origin count retrasos med_distancia
#1 D942DN JFK 1 2 944.0000
#2 D942DN LGA 3 124 824.6667
#3 N0EGMQ EWR 48 531 719.0000
#4 N0EGMQ JFK 27 361 517.6667
#5 N0EGMQ LGA 277 2622 688.2816
#6 N10156 EWR 144 1706 758.6458

max(plane1$count)
#536
filter(plane1,count==536)
#Source: local data frame [1 x 5]
#Groups: tailnum

#tailnum origin count retrasos med_distancia
#1 N725MQ LGA 536 2508 561.4515

De este modo tenemos que N725MQ es el registro que tienen mayor cantidad de vuelos. Entonces filtro la información original para analizar solo los datos correspondientes a este registro.

#Filtro
Plane_N725MQ=filter(flights2,tailnum=="N725MQ")
#Observo en breve la información
head(Plane_N725MQ)
#Source: local data frame [6 x 16]

#year month day dep_time dep_delay arr_time arr_delay carrier tailnum
#1 2013 1 1 832 -8 1006 -24 MQ N725MQ
#2 2013 1 1 1305 -10 1523 3 MQ N725MQ
#3 2013 1 1 1840 -5 2055 25 MQ N725MQ
#4 2013 1 2 1205 0 1349 4 MQ N725MQ
#5 2013 1 2 1805 -5 1946 1 MQ N725MQ
#6 2013 1 3 1131 -4 1314 -16 MQ N725MQ
#Variables not shown: flight (int), origin (chr), dest (chr), air_time (dbl),
# distance (dbl), hour (dbl), minute (dbl)

#Agrego dos variables nuevas
Plane_N725MQ1=mutate(Plane_N725MQ,velocidad=distance/air_time*60,fechas=as.Date(paste(month,day,year,sep="/"),"%m/%d/%Y"))

Con lo anterior puedo seleccionar las columnas que deseo analizar y por medio de la librería Reshape2 puedo cambiar su estructura para apreciar su comportamiento con respecto al tiempo, es decir; como serie de tiempo.

#Explorando el comportamiento de su velocidad media y la media de retrasos al arribar

#Se procesan los datos para construir otra estructura de datos 

B1<-Plane_N725MQ1%>%
 group_by(fechas,origin, dest)%>%
 summarise(count=n(),retrasos=mean(arr_delay),vel_media=mean(velocidad))

head(B1)
Source: local data frame [6 x 6]
Groups: fechas, origin

 fechas origin dest count retrasos vel_media
1 2013-01-01 LGA CRW 1 25 277.5000
2 2013-01-01 LGA DTW 1 3 295.2941
3 2013-01-01 LGA RDU 1 -24 335.8442
4 2013-01-02 LGA BNA 1 1 342.0896
5 2013-01-02 LGA RDU 1 4 300.6977
6 2013-01-03 LGA CLE 1 -16 318.2278

#Gráficas para explorar el comportamiento en el año

ggplot(B1,aes(x=fechas,y=vel_media,colour=dest))+geom_line()+scale_x_date()+geom_smooth(col="black")+
 ggtitle("Comportamiento de la velocidad en el año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Velocidad media de vuelo")+xlab("Fecha de Vuelos")

ggplot(B1,aes(x=fechas,y=retrasos,colour=dest))+geom_line()+scale_x_date()+geom_smooth(col="black")+
 ggtitle("Comportamiento de los retrasos en el año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Media de los retraos en los vuelos")+xlab("Fecha de Vuelos")

Las gráficas que se obtienen son las siguientes:

N725MQ

N725MQ_retrasos

En las dos gráficas se aprecian comportamiento peculiares para ciertos destinos de vuelo, cada sigue un comportamiento. En la primera gráficas resalta el comportamiento de BNA y CLE, el primero está sobre la línea de tendencia y el segundo tiene bajas de media de velocidad considerables para el periodo de Abril a Julio.

En la segunda gráfica se aprecia un comportamiento de mayor media en los retrasos entre los meses de Abril-Mayo y en otro momento en los meses de Junio-Julio.

En resumen, esta exploración permite centralizar el análisis en los destinos que resultan con comportamiento más extraños, con esta sospecha se puede procesar la información para analizar como se comportan el resto de vuelos con respecto a esos destinos.

Otro modo de procesar los datos  y realizar el análisis es revisar como se comportan los retrasos pero dividida por aeropuerto de origen de vuelo, esto se puede hacer fácil haciendo uso de la función melt de la librería Reshape2.

#Separación del análisis

#Se procesan lo datos originales
B2<-Plane_N725MQ1%>%
 group_by(fechas,origin, dest)%>%
 summarise(retrasos_arr=mean(arr_delay),retrasos_dep=mean(dep_delay))

#Construyo una table que permita el análisis de los datos de manera sencilla

datos=melt(B2,id=c("fechas","origin","dest"))

#Con el comando head() se visualiza como se ordena la información
head(datos)
#     fechas origin dest variable value
#1 2013-01-01 LGA CRW retrasos_arr 25
#2 2013-01-01 LGA DTW retrasos_arr 3
#3 2013-01-01 LGA RDU retrasos_arr -24
#4 2013-01-02 LGA BNA retrasos_arr 1
#5 2013-01-02 LGA RDU retrasos_arr 4
#6 2013-01-03 LGA CLE retrasos_arr -16

#Se analizan los datos gráficamente

ggplot(data=datos,aes(x=fechas,y=value,colour=dest,group=variable))+geom_line()+scale_x_date()+
 ggtitle("Comportamiento de los retrasos en el año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Media de los retraos en los vuelos")+xlab("Fecha de Vuelos")+
 facet_grid(.~origin)

La gráfica es la siguiente:

Retrasos_origen-destino

En este último ejemplo queda claro cual es el aeropuerto que se usa para despegar y el comportamiento de las medias de retrasos muestra ciertos picos, una ligera alza en los meses de Junio-Julio-Agosto. Este último gráfico se puede obtener desde la primera estructura de datos analizada, la única finalidad de hacer este último ejemplo era mostrar como melt() modifica la información no regresa algo parecido a una tabla pivot de Excel.

La última es prácticamente equivalente a la que se puede consultar en la página de referencia de dplyr, lo único que agregué fue mostrar la referencia de origen de vuelo.

#Última clasificación
#Se agrupan por 2 columnas
by_tailnum <- group_by(flights, tailnum,origin)
head(by_tailnum)
#Se construye el resumen de los datos
 
delay <- summarise(by_tailnum,
 count = n(),
 dist = mean(distance, na.rm = TRUE),
 delay = mean(arr_delay, na.rm = TRUE))

delay <- filter(delay, count > 20, dist < 2000)

#Se genera la gráfica para ver el cruce

ggplot(delay, aes(dist, delay)) +
 geom_point(aes(size = count,colour=origin), alpha = 1/2) +
 geom_smooth() +
 scale_size_area()+
 xlab('Media de la Distancia')+
 ylab('Media de los Retrasos')+
 ggtitle('Cruce de la media de las distancia vs media de los retrasos')+
 theme(plot.title=element_text(lineheight = 1,face='bold'))

La gráfica que se obtiene es la siguiente:

Cruce_dist_vs_retrasos

El patrón que se muestra posiblemente pueda ser estudiado con alguna técnica de clasificación la cual indicaría un aproximado de como se aglomera la información, pensando burdamente en usar cluster supongo que jugando con 5 cluster podría obtenerse un modelo simple sobre los datos.

En Python

PENDIENTE

Anuncios

Un comentario sobre “Split-Apply-Combine-Parte 2

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s