1 Parte 1


1.1 Introducción

Web scraping es una técnica utilizada mediante programas de software para extraer información de sitios web. Usualmente, estos programas simulan la navegación de un humano en la World Wide Web ya sea utilizando el protocolo HTTP manualmente, o incrustando un navegador en una aplicación.

El web scraping se enfoca más en la transformación de datos sin estructura en la web (como el formato HTML) en datos estructurados que pueden ser almacenados y analizados en una base de datos central, en una hoja de cálculo o en alguna otra fuente de almacenamiento. El término web scraping también está relacionado con la automatización de tareas en la Web, la cual simula la navegación de un humano utilizando un software de computadora. Alguno de los usos del web scraping son la comparación de precios en tiendas, la monitorización de datos relacionados con el clima de cierta región, la detección de cambios en sitios webs y la integración de datos en sitios webs. También es utilizado para obtener información relevante de un sitio a través de los rich snippets Fuente: Wikipedia.

1.2 Objetivo

Lo que queremos hacer es obtener información sobre accidentes aéreos. La información esta contenida en la página http://aviation-safety.net

alt text

Para ver la información vayamos a Database. Aquí podemos ver todos los accidentes aéreos desde el año 1919 hasta el año 2015.

alt text

Ahora hagamos clic en el ano 2015 para ver que información tenemos.

alt text

Podemos ver que tenemos una tabla. Se lista la información de las ochos columnas dadas a continuación,

  1. date = fecha del incidente.
  2. type = tipo de avión.
  3. registration = registro del avión.
  4. operator = operador del vuelo.
  5. fat. = fatalidades del incidente.
  6. location = lugar del incidente.
  7. pic = foto del incidente.
  8. cat = categoría
    • A = accidente
    • I = incidente
    • H = secuestro
    • C = ocurrencia criminal (sabotaje, derribado)
    • O = otros
    • 1 = perdida total
    • 2 = daño reparable

Además si hacemos clic en la fecha 18-JAN-2015 podemos accesar todavía mas información.

alt text

Aquí podemos encontrar una descripción mas detallada del accidente. Por ejemplo, cuando fue el primer vuelo, en la fase de vuelo que fue el accidente y el tipo de avión que era, en este caso militar(podría ser de cargo, pasajeros, entre otros ).

1.3 Primera parte

Iniciaremos obteniendo la información que nos da la página http://aviation-safety.net/database/ . Para lograr este crearemos una función en R que nos devuelva esta información en formato de dataframe y que reciba el año que queremos obtener.

1.3.1 Funciones

La funciones en R tiene el siguiente formato,

nombre_de_funcion <- function(parmetro1=valor, parámetro2 = valor){
        ##Codigo
        return(out)
}

A forma de ejemplo hagamos una función que eleve un numero a la potencia n,

potencia <- function(numero=1,n=2){
        salida<-numero^n
        return(salida)
}

Notemos que numero es nuestro primer parámetro y n el segundo. Les estamos dando el valor inicial de numero = 1 y n = 2, esto es opcional. Lo que haría esta función es tomar numero y elevarlo a la n potencia es decir \(\text{numero}^n\). Probemos nuestra función,

potencia()
## [1] 1

Cuando no ponemos valores R usa los valor por defecto que nosotros le pusimos a la función en este caso es como que si hubiéramos llamado a la función de la forma ´potencia(1,2)´ probemos hacer \(8^3\),

potencia(8,3)
## [1] 512

1.3.2 Función get_data

La función ´get_data()´ es la que nosotros construiremos para obtener la información de los accidentes aéreos. Tiene que tener la siguiente estructura,

get_data <- function(year){
        ##codigo
}

Para poder armar nuestra función tenemos que analizar el url de la página. El url se ve así,

http://aviation-safety.net/database/dblist.php?Year=2010&lang=&page=1

Podemos ver que la primera parte http://aviation-safety.net/database/dblist.php es el php que hace el requisito a la base de datos y después vienen dos variables, la variable Year y la variable page. la primera tiene el valor de 2010 y la segunda tiene el valor de uno. Esto quiere decir que esta llamando la información del año 2010 y la primera página. Probemos cambiar el 1 por el 2, después el 2010 por el 2011 y podremos ver que variando estos valores obtenemos la información del año y página que queramos. Esto es lo que manipularemos con R.

Agreguemos lo siguiente a nuestra función get_data()

get_data <- function(year){
        url<-paste("http://aviation-safety.net/database/dblist.php?Year=",year,"&lan=&page=1", sep="") 
        return(url)
}

la función paste() es la alternativa en R para concatenar strings. En este caso estamos concatenando la variable year a la dirección y estamos guardándola en la variable url y la función por ahora devuelve el valor de la variable url, probemos la,

get_data(2010)
## [1] "http://aviation-safety.net/database/dblist.php?Year=2010&lan=&page=1"
get_data(1999)
## [1] "http://aviation-safety.net/database/dblist.php?Year=1999&lan=&page=1"

Todo va muy bien, ahora queremos obtener la información que esta en url e ingresarla a R. Para esto usaremos la librería XML instalaremos la librería usando el código install.packages("XML") y después carguemos la usando library(XML).

La función que nos interesa de esta librería es readHTMLTable() esta función va al url y descarga la tabla. Agreguemos la a nuestra función.

get_data <- function(year){
        require(XML)
        url<-paste("http://aviation-safety.net/database/dblist.php?Year=",year,"&lan=&page=1", sep="") 
        data<-readHTMLTable(url,wich=1,stringsAsFactors=FALSE)
        return(data)
}

El parámetro wich=1 le dice a la función readHTMLTable() que queremos la primera tabla que aparezca, podríamos pedir la segunda, tercera, etc.

Analicemos el resultado de nuestra función,

data<-get_data(2010)
## Loading required package: XML
str(data)
## List of 1
##  $ NULL:'data.frame':    100 obs. of  9 variables:
##   ..$ date        : chr [1:100] "02-JAN-2010" "02-JAN-2010" "04-JAN-2010" "05-JAN-2010" ...
##   ..$ type        : chr [1:100] "Boeing 727-231F Super 27" "Swearingen SA227-AC Metro III" "Antonov 12BK" "Learjet 35A" ...
##   ..$ registration: chr [1:100] "9Q-CAA" "N227ML" "ST-AQQ" "N720RA" ...
##   ..$ operator    : chr [1:100] "CAA" "Locair" "El Magal Aviation" "Royal Air Freight" ...
##   ..$ fat.        : chr [1:100] "0" "0" "0" "2" ...
##   ..$ location    : chr [1:100] "Kinshasa-N'D..." "Somerset-Lak..." "Heglig Airport" "near Chicago-Exec..." ...
##   ..$ <c2><a0>    : chr [1:100] "" "" "" "" ...
##   ..$ pic         : chr [1:100] "<c2><a0>" "" "<c2><a0>" "" ...
##   ..$ cat         : chr [1:100] "A1" "A2" "A1" "A1" ...

es una lista de solo un elemento que es un data frame, obtengamos ese data frame.

data<-data[[1]]
str(data)
## 'data.frame':    100 obs. of  9 variables:
##  $ date        : chr  "02-JAN-2010" "02-JAN-2010" "04-JAN-2010" "05-JAN-2010" ...
##  $ type        : chr  "Boeing 727-231F Super 27" "Swearingen SA227-AC Metro III" "Antonov 12BK" "Learjet 35A" ...
##  $ registration: chr  "9Q-CAA" "N227ML" "ST-AQQ" "N720RA" ...
##  $ operator    : chr  "CAA" "Locair" "El Magal Aviation" "Royal Air Freight" ...
##  $ fat.        : chr  "0" "0" "0" "2" ...
##  $ location    : chr  "Kinshasa-N'D..." "Somerset-Lak..." "Heglig Airport" "near Chicago-Exec..." ...
##  $ <c2><a0>    : chr  "" "" "" "" ...
##  $ pic         : chr  "<c2><a0>" "" "<c2><a0>" "" ...
##  $ cat         : chr  "A1" "A2" "A1" "A1" ...

Como podemos ver ya tenemos los datos en R. Probemos otro año y vemos los primeros 15 valores,

data<-get_data(2015)
data<-data[[1]]
head(data,15)
##           date                           type registration
## 1  02-JAN-2015                      Saab 340B       G-LGNL
## 2  03-JAN-2015                    Antonov 26B     RA-26082
## 3  10-JAN-2015               Boeing 737-43QSF       ET-AQV
## 4  11-JAN-2015           DHC-6-300 Twin Otter       PK-YRU
## 5  16-JAN-2015               BN-2A-8 Islander       YV2238
## 6  17-JAN-2015  Bombardier BD-700 Global 5000     RP-C9363
## 7  18-JAN-2015                     Antonov 26       YK-AND
## 8  20-JAN-2015                      Antonov 2     UP-A0314
## 9  20-JAN-2015                 BN-2T Islander       ZS-NAT
## 10 26-JAN-2015            Boeing 737-8KN (WL)       A6-FEK
## 11 29-JAN-2015 Canadair CL-600 Challenger 601       N214FW
## 12 30-JAN-2015                   Ilyushin 76T       5A-DNK
## 13 02-FEB-2015          BAe 4100 Jetstream 41       SX-DIA
## 14 04-FEB-2015           ATR 72-600 (72-212A)      B-22816
## 15 11-FEB-2015               Beechcraft 1900C       YV1674
##                                    operator fat.             location
## 1                      Loganair, opf. Flybe    0      Stornoway Ai...
## 2                                 KAPO Avia    0      Magadan-Soko...
## 3    Ethiopian Airlines, opf. ASKY Airlines    0      Accra-Kotoka...
## 4                       Trigana Air Service    0      Enarotali Ai...
## 5                                 Chapi Air    0      Los Roques A...
## 6  Challenger Aero Corporation Metro Manila    0      Tacloban Air...
## 7                          Syrian Air Force   30 near Abu adh Dhuh...
## 8                                 Olimp Air    6  near Shatyrkul Mine
## 9                             Xcel Aviation    0      Dawlatabad D...
## 10                                 flydubai    0 near Baghdad Inte...
## 11                           Dinama Aircorp    3      near Boca Druif
## 12                         Libyan Air Cargo    0      Tripoli-Miti...
## 13                              Sky Express    0      Rhodes/Parad...
## 14                        TransAsia Airways   43 near Taipei-Sung ...
## 15                         Aeropanamericano    4 near Miami Execut...
##    <c2><a0>       pic cat
## 1            <c2><a0>  A2
## 2            <c2><a0>  A2
## 3            <c2><a0>  A2
## 4                      A2
## 5            <c2><a0>  A2
## 6            <c2><a0>  A2
## 7            <c2><a0>  A1
## 8            <c2><a0>  A1
## 9            <c2><a0>  A2
## 10           <c2><a0>  C2
## 11           <c2><a0>  C1
## 12                     C1
## 13                     A2
## 14                     A1
## 15           <c2><a0>  A1

Ya vamos por el 25% de trabajo. Ahora, si revisamos la página

http://aviation-safety.net/database/dblist.php?Year=2010&lang=&page=1

podemos ver que tiene dos páginas. La variable page toma entonces el valor de 1 o el valor de 2. Pero en el caso del año 1987

http://aviation-safety.net/database/dblist.php?Year=1987&lang=&page=1

tenemos que la variable page puede tomar los valores de 1, 2 ó 3. Ahora en el caso del 2015

http://aviation-safety.net/database/dblist.php?Year=2015&lang=&page=1

la variable pagesolo puede tomar el valor de 1, es más, no sabemos a ciencia cierta si hay alguna que tenga más de 3 páginas entonces necesitamos variar la variable page en todos los posibles valores y obtener la información de cada una de estas direcciones. Para hacer esto usaremos un ciclo while.

Lo que queremos hacer con el while es que cuando llegue al número máximo de valores que puede tomar la variable page que se salga del ciclo, entonces necesitamos una variable que nos sirva como bandera para salirnos del while, entonces crearemos la variable booleana bandera. Muy bien modifiquemos nuestra función.

get_data <- function(year){
        require(XML)
        bandera<-FALSE ##(1)
        i<-2 ## (2)
        url<-paste("http://aviation-safety.net/database/dblist.php?Year=",year,"&lan=&page=1", sep="") 
        data<-readHTMLTable(url,wich=1,stringsAsFactors=FALSE)
        out<-data[[1]] ##(3)
        ##########################(4) Inicio While############################
        while(bandera==FALSE){
                url<-paste("http://aviation-safety.net/database/dblist.php?Year=",year,"&lan=&page=",i, sep="")##(4.1)
                data1<-readHTMLTable(url,wich=1,stringsAsFactors=FALSE) ##(4.2)
                bandera<-is.null(data1[[1]]) ## (4.3)
                if(bandera==FALSE){  ### (4.4) 
                        out<-rbind(out,data1[[1]]) ###(4.5)
                }
                i<-i+1 ###(4.6)
        }
        ###########################Fin While####################################
        return(out) ### (5)
}

Podemos ver que agregamos varias lìneas a nuestra función, analizaremos cada una de las nuevas partes de nuestra función get_data()

  1. bandera<-FALSE Ésta es la variable que usaremos para detener el while cuando hayamos recorrido todas las páginas.
  2. i<-2 Ésta variable nos ayudará a cambiar los valores de la variable page.
  3. out<-data[[1]] Data tiene el contenido de page=1 entonce lo guardamos en la variable out.
  4. Aquí tenemos el inicio de nuestro while, este ciclo se repetirá hasta que bandera==TRUE.
    • (4.1) url<-paste("http://aviation-safety.net/database/dblist.php?Year=",year,"&lan=&page=",i, sep="") esta línea de código está guardando en url la dirección de la página i.
    • (4.2) data1<-readHTMLTable(url,wich=1,stringsAsFactors=FALSE) Guardamos en data1 el resultado de la función readHTMLTable(). Si no existe la página devuelve un data frame vácio (NULL).
    • (4.3) bandera<-is.null(data1[[1]]) La función is.null(x) es verdadera si x es NULL. Ahora si es NULL cambiara el valor de bandera a TRUE y se saldrá del ciclo while y esto señala que ya recorrimos todos los valores de la variable page.
    • (4.4) if(bandera==FALSE){ Inicio del if que revisa si la función readHTMLTable() devolvió un dataframe con datos o devolvió un dataframe vácio (NULL). Si tiene datos entra al IF y se va a la línea (4.5).
    • (4.5) out<-rbind(out,data1[[1]]) La función rbind() agrega filas a un dataframe. Por ejemplo, si tenemos rbind(x,y) está función regresa un dataframe con todas las filas de x al inicio y todas las filas de y al final. Entonces en este caso lo que estamos haciendo es tomando el dataframe out y le estamos agregando las filas de data1 y el resultado lo agregamos de nuevo a out.
    • (4.6) i<-i+1 aumentamos la variable i para cambiarnos de página.
  5. Devolvemos el resultado completo para el año year. Con todos los valores de la variable page.

Probemos nuestra función,

data<-get_data(2011)
data[,c(1,2,5)]
##            date                                type  fat.
## 1   01-JAN-2011                      Tupolev 154B-2     3
## 2   03-JAN-2011            Beechcraft B200 King Air     0
## 3   05-JAN-2011                 Boeing 737-8F2 (WL)     0
## 4   06-JAN-2011                         Learjet 35A     0
## 5   06-JAN-2011           Cessna 208B Grand Caravan     0
## 6   07-JAN-2011      Beechcraft B200 Super King Air     0
## 7   09-JAN-2011                      Boeing 727-286    77
## 8   10-JAN-2011                     Airbus A320-216     0
## 9   10-JAN-2011                      Boeing 737-2T5     0
## 10  14-JAN-2011      Beechcraft B200 Super King Air     6
## 11  17-JAN-2011          DHC-3T Vazar Turbine Otter     0
## 12  17-JAN-2011                   Convair CV-340-71     0
## 13  19-JAN-2011           Cessna 208B Grand Caravan     0
## 14  20-JAN-2011                DHC-6 Twin Otter 300     6
## 15  27-JAN-2011       Fokker F-27 Friendship 500CRF     0
## 16  30-JAN-2011                     Gulfstream G-IV     0
## 17  04-FEB-2011               Raytheon Hawker 850XP     7
## 18  09-FEB-2011                    Beechcraft 1900D     0
## 19  10-FEB-2011       Swearingen SA227-BC Metro III     6
## 20  12-FEB-2011 CASA/Nurtanio NC-212-A4 Aviocar 100     5
## 21  14-FEB-2011                    Let L-410UVP-E20    14
## 22  14-FEB-2011                        Let L-410UVP     2
## 23  14-FEB-2011             Gulfstream GV-SP (G550)     0
## 24  16-FEB-2011            Cessna 525 Citation CJ1+     0
## 25  16-FEB-2011                      Boeing 747-368     0
## 26  18-FEB-2011                          Learjet 24     2
## 27  21-FEB-2011                          ATR-72-212     0
## 28  27-FEB-2011        Swearingen SA227-DC Metro 23     0
## 29  02-MAR-2011       Swearingen SA227-AC Metro III     0
## 30  02-MAR-2011           Cessna S550 Citation S/II     0
## 31  04-MAR-2011                           DHC-8-106     0
## 32  05-MAR-2011                    Antonov 148-100E     6
## 33  05-MAR-2011       Beechcraft 200 Super King Air     0
## 34  08-MAR-2011                DHC-6 Twin Otter 100     2
## 35  11-MAR-2011   Beechcraft 300 Super King Air 350     0
## 36  11-MAR-2011                Cessna 208 Caravan I     0
## 37  11-MAR-2011                Cessna 208 Caravan I     0
## 38  12-MAR-2011    Bombardier BD-100 Challenger 300     0
## 39  16-MAR-2011       Beechcraft 200 Super King Air     5
## 40  17-MAR-2011                         Yakovlev 40     0
## 41  17-MAR-2011                       Yakovlev 40KD     0
## 42  17-MAR-2011                      Boeing 737-2D6     0
## 43  20-MAR-2011                     Convair CV-580F     0
## 44  21-MAR-2011                        Antonov 12BP 9+ 14
## 45  23-MAR-2011                 Dassault Falcon 100     0
## 46  28-MAR-2011              Cessna 550 Citation II     3
## 47  30-MAR-2011                          Antonov 2R     0
## 48  31-MAR-2011          DHC-3T Texas Turbine Otter     1
## 49  01-APR-2011                 Boeing 737-3H4 (WL)     0
## 50  01-APR-2011         CASA C-212-CC40 Aviocar 200     1
## 51  02-APR-2011                     Gulfstream G650     4
## 52  04-APR-2011     Canadair Regional Jet CRJ-100ER    32
## 53  11-APR-2011                         Antonov 2TP     0
## 54  13-APR-2011                     Airbus A330-203     0
## 55  16-APR-2011                        Yakovlev 40K     0
## 56  17-APR-2011                      Boeing 777-F6N     0
## 57  26-APR-2011       Cessna 208B Super Cargomaster     0
## 58  28-APR-2011       Embraer EMB-145EP (ERJ-145EP)     0
## 59  04-MAY-2011           Cessna 208B Grand Caravan     0
## 60  07-MAY-2011                           Xian MA60    25
## 61  10-MAY-2011                           Fokker 50     0
## 62  16-MAY-2011      Beechcraft B200 Super King Air     0
## 63  17-MAY-2011                          Antonov 2R     0
## 64  18-MAY-2011                           Saab 340A    22
## 65  18-MAY-2011                     Boeing 707-321B     0
## 66  23-MAY-2011           Cessna 208B Grand Caravan     0
## 67  25-MAY-2011          Embraer EMB-500 Phenom 100     0
## 68  28-MAY-2011          DHC-3T Vazar Turbine Otter     0
## 69  01-JUN-2011                         Eclipse 500     0
## 70  06-JUN-2011                          Antonov 26     0
## 71  08-JUN-2011                    CASA CN-235M-200     0
## 72  08-JUN-2011                   BN-2B-26 Islander     0
## 73  12-JUN-2011                      Douglas DC-6BF     0
## 74  15-JUN-2011            Beechcraft A100 King Air     0
## 75  17-JUN-2011                           Antonov 2     0
## 76  17-JUN-2011                  Dassault Falcon 10     0
## 77  20-JUN-2011                      Tupolev 134A-3    47
## 78  24-JUN-2011                          Antonov 2R     0
## 79  04-JUL-2011           Cessna 208B Grand Caravan     1
## 80  06-JUL-2011                       Ilyushin 76TD     9
## 81  08-JUL-2011                 Boeing 727-022 (WL)    77
## 82  10-JUL-2011         Hawker Siddeley HS-125-700B     0
## 83  11-JUL-2011                        Antonov 24RV     7
## 84  11-JUL-2011                DHC-6 Twin Otter 310     0
## 85  13-JUL-2011                    Let L-410UVP-E20    16
## 86  14-JUL-2011                          ATR 72-202     0
## 87  14-JUL-2011           Cessna 560XL Citation XLS     0
## 88  17-JUL-2011                          ATR 72-212     0
## 89  26-JUL-2011            Lockheed C-130H Hercules    80
## 90  27-JUL-2011                          Antonov 2R     0
## 91  28-JUL-2011                     Boeing 747-48EF     2
## 92  29-JUL-2011                    Boeing 777-266ER     0
## 93  30-JUL-2011                 Boeing 737-8BK (WL)     0
## 94  30-JUL-2011     Canadair Regional Jet CRJ-200ER     0
## 95  02-AUG-2011   Cessna 208B Grand Caravan (C-98A)     8
## 96  08-AUG-2011                        Antonov 24RV     0
## 97  09-AUG-2011                        Antonov 12AP    11
## 98  15-AUG-2011             Lockheed C-130 Hercules     0
## 99  20-AUG-2011                     Boeing 737-210C    12
## 100 22-AUG-2011                           Antonov 2     1
## 101 24-AUG-2011                DHC-6 Twin Otter 310     0
## 102 25-AUG-2011                   Airbus A300B4-620     0
## 103 25-AUG-2011                  Airbus A300B4-622R     0
## 104 25-AUG-2011                     Airbus A320-214     0
## 105 26-AUG-2011                         Ilyushin 76     0
## 106 28-AUG-2011                          Antonov 2R     1
## 107 29-AUG-2011                     Airbus A320-214     0
## 108 31-AUG-2011                          Antonov 2T     0
## 109 02-SEP-2011           Cessna 208B Grand Caravan     1
## 110 02-SEP-2011            CASA C-212 Aviocar 300DF    21
## 111 03-SEP-2011                          Antonov 2R     1
## 112 04-SEP-2011       Embraer EMB-145LR (ERJ-145LR)     0
## 113 06-SEP-2011       Swearingen SA227-BC Metro III     8
## 114 07-SEP-2011                        Yakovlev 42D    44
## 115 09-SEP-2011           Cessna 208B Grand Caravan     2
## 116 09-SEP-2011                         Antonov 2TD     0
## 117 14-SEP-2011              Embraer 120ER Brasilia    17
## 118 16-SEP-2011 Embraer ERJ 190-100 IGW (ERJ-190AR)     0
## 119 20-SEP-2011                      Beechcraft 99A     3
## 120 22-SEP-2011                DHC-6 Twin Otter 300     2
## 121 23-SEP-2011          DHC-3T Texas Turbine Otter     1
## 122 25-SEP-2011                    Beechcraft 1900D    19
## 123 26-SEP-2011                             DC-9-51     0
## 124 29-SEP-2011    CASA/Nurtanio NC-212 Aviocar 200    18
## 125 ??-SEP-2011                DHC-6 Twin Otter 300     0
## 126 02-OCT-2011                           Fokker 50     0
## 127 03-OCT-2011                 Dassault Falcon 20F     0
## 128 04-OCT-2011           Cessna 208B Grand Caravan     2
## 129 09-OCT-2011                          Antonov 2R     0
## 130 10-OCT-2011                      Boeing 737-4Q8     0
## 131 12-OCT-2011              Embraer 120ER Brasilia     0
## 132 13-OCT-2011                           DHC-8-102    28
## 133 14-OCT-2011           Cessna 208B Grand Caravan     8
## 134 14-OCT-2011              Cessna 550 Citation II     0
## 135 18-OCT-2011      Pilatus BN-2T Turbine Islander     6
## 136 25-OCT-2011                             Antonov     4
## 137 25-OCT-2011            Beechcraft Beechjet 400A     0
## 138 27-OCT-2011             Beechcraft 100 King Air     2
## 139 31-OCT-2011                     Gulfstream G150     0
## 140 ??-OCT-2011                          Antonov 28     0
## 141 01-NOV-2011                    Boeing 767-35DER     0
## 142 10-NOV-2011                           Fokker 50     0
## 143 23-NOV-2011           Cessna 208B Grand Caravan     1
## 144 30-NOV-2011                     Beechcraft 1900     0
## 145 ??-NOV-2011             Cessna S550 Citation II     0
## 146 03-DEC-2011        CASA/IPTN NC-212 Aviocar 200     0
## 147 04-DEC-2011            Beechcraft A100 King Air     0
## 148 12-DEC-2011                           Antonov 2     0
## 149 15-DEC-2011                          Antonov 32     0
## 150 17-DEC-2011                Cessna 208 Caravan I     0
## 151 18-DEC-2011 PZL-Mielec C-145A (M28-05) Skytruck     0
## 152 20-DEC-2011                      Boeing 737-36M     0
## 153 28-DEC-2011                      Tupolev 134A-3     0
## 154 28-DEC-2011             Cessna 650 Citation VII     0

Como podemos ver ya nos devuelve todos los valores para el año recorriendo todos los valores de page.

Podemos identificar el primer problema con nuestra data, vemos la línea 44 del año 2011,

data<-get_data(2011)
data[44,c(1,2,5)]
##           date         type  fat.
## 44 21-MAR-2011 Antonov 12BP 9+ 14

el problema es con la variable fat. porque en lugar de tener un valor numérico tenemos la operación de 9+14 esto es porque murieron 9 que viajaban en el avión y 14 que estaban en tierra. Necesitamos suma estos valores. Entonces modifiquemos nuestra función get_data para poder manejar estos valores,

get_data <- function(year){
        require(XML)
        require(dplyr)
        bandera<-FALSE
        i<-2 
        url<-paste("http://aviation-safety.net/database/dblist.php?Year=",year,"&lan=&page=1", sep="") 
        data<-readHTMLTable(url,wich=1,stringsAsFactors=FALSE)
        out<-data[[1]] 
        while(bandera==FALSE){
                url<-paste("http://aviation-safety.net/database/dblist.php?Year=",year,"&lan=&page=",i, sep="")
                data1<-readHTMLTable(url,wich=1,stringsAsFactors=FALSE) 
                bandera<-is.null(data1[[1]])
                if(bandera==FALSE){  
                        out<-rbind(out,data1[[1]]) 
                }
                i<-i+1 
        }
        out<-tbl_df(out) ##(1)
        out<-out%>%filter(fat.!="") ##(2)
        x<-parse(text=out$fat.) ##(3)
        y<-as.numeric(lapply(x, eval)) ##(4)
        out$fat.<-y ##(5)
        return(out)
}

Podemos ver que agregamos varias líneas a nuestra función, analizaremos cada una de las nuevas partes de nuestra función get_data()

  1. (1) convertimos out en un dataframe para usar la librería dplyr.
  2. (2) quitamos todos los valores de la variable fat. que estén vacíos.
  3. (3) La función parse() cambia el string 9+14 a una expresión numérica para poder ser evaluada.
  4. (4) En está línea pasan varias cosas analicemos una por una,
    • La función lapply(data,fun) aplica la función fun a cada uno de los elementos de data. Entonces los que estamos haciendo aquí es aplicando a x la función eval(). La función eval() evaluar los resultados de la función parse().
    • la función lapply() desvuelve una lista con todos los valores, la función as.numeri() convierte la lista en un vector numérico. Este resultado lo guardamos en la variable y.
  5. (5) En está línea estamos cambiando los valores anteriores de la variable fat. por los nuevos valores ya evaluados que tenemos guardados en nuestra variable y.
data<-get_data(2011)
data[44,c(1,2,5)]
## Source: local data frame [1 x 3]
## 
##          date         type fat.
## 1 21-MAR-2011 Antonov 12BP   23

Como podemos ver ya hizo lo operación, también forzamos la variable fat. a que sea de tipo numeric veamos la estructura de data.

data<-get_data(2011)
str(data[,c(1,2,3,4,5)])
## Classes 'tbl_df' and 'data.frame':   154 obs. of  5 variables:
##  $ date        : chr  "01-JAN-2011" "03-JAN-2011" "05-JAN-2011" "06-JAN-2011" ...
##  $ type        : chr  "Tupolev 154B-2" "Beechcraft B200 King Air" "Boeing 737-8F2 (WL)" "Learjet 35A" ...
##  $ registration: chr  "RA-85588" "C-GSAU" "TC-JGZ" "N800GP" ...
##  $ operator    : chr  "Kolavia" "Saskatchewan Gvt." "THY" "Priester Aviation" ...
##  $ fat.        : num  3 0 0 0 0 0 77 0 0 6 ...

podemos ver que la variable fat. ya es del tipo numeric. Ahora otro problema que vemos con nuestra data es que la variable data es del tipo char cuando debería de ser del tipo date. Hagamos esta modificación a nuestra función,

get_data <- function(year){
        require(XML)
        require(dplyr)
        bandera<-FALSE
        i<-2 
        url<-paste("http://aviation-safety.net/database/dblist.php?Year=",year,"&lan=&page=1", sep="") 
        data<-readHTMLTable(url,wich=1,stringsAsFactors=FALSE)
        out<-data[[1]] 
        while(bandera==FALSE){
                url<-paste("http://aviation-safety.net/database/dblist.php?Year=",year,"&lan=&page=",i, sep="")
                data1<-readHTMLTable(url,wich=1,stringsAsFactors=FALSE) 
                bandera<-is.null(data1[[1]])
                if(bandera==FALSE){  
                        out<-rbind(out,data1[[1]]) 
                }
                i<-i+1 
        }
        out<-tbl_df(out) ##(1)
        out<-out%>%filter(fat.!="")
        x<-parse(text=out$fat.)
        y<-as.numeric(lapply(x, eval))
        out$fat.<-y 
        out$date<-as.Date(out$date,"%d-%b-%Y") ### (1)
        return(out)
}

En este caso sólo tuvimos que agregar la línea (1). Para hacer el cambio usamos la función as.Date() donde out$date es nuestra columna con la fechas en tipo chr y nosotros la queremos cambiar al tipo date. También nótese que agregamos "%d-%b-%Y" como segundo argumento, esto lo hicimos para decirle a R el formato que tiene la fecha %d es por que primero aparece el día, %b es porque aparece después el mes abreviado con tres siglas y por ultimo %Y por que aparece el año con cuatro dígitos. Todos estos separados por un guion. Es importante leer la ayuda de esta función ya que se usara mucho. Vemos como queda ahora la estructura de nuestra data.

data<-get_data(2011)
str(data[,c(1,2,3,4,5)])
## Classes 'tbl_df' and 'data.frame':   154 obs. of  5 variables:
##  $ date        : Date, format: "2011-01-01" "2011-01-03" ...
##  $ type        : chr  "Tupolev 154B-2" "Beechcraft B200 King Air" "Boeing 737-8F2 (WL)" "Learjet 35A" ...
##  $ registration: chr  "RA-85588" "C-GSAU" "TC-JGZ" "N800GP" ...
##  $ operator    : chr  "Kolavia" "Saskatchewan Gvt." "THY" "Priester Aviation" ...
##  $ fat.        : num  3 0 0 0 0 0 77 0 0 6 ...

podemos ver que el cambio esta hecho lo que antes aparecía como “01-JAN-2011” en tipo chr ahora aparece como “2011-01-01” en formato date (YYYY-MM-DD).

Muy bien con esto terminamos de construir nuestra función get_data().