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.
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
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.
Ahora hagamos clic en el ano 2015 para ver que información tenemos.
Podemos ver que tenemos una tabla. Se lista la información de las ochos columnas dadas a continuación,
Además si hacemos clic en la fecha 18-JAN-2015 podemos accesar todavía mas información.
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 ).
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.
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
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 page
solo 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()
bandera<-FALSE
Ésta es la variable que usaremos para detener el while cuando hayamos recorrido todas las páginas.i<-2
Ésta variable nos ayudará a cambiar los valores de la variable page
.out<-data[[1]]
Data tiene el contenido de page=1
entonce lo guardamos en la variable out
.bandera==TRUE
.
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
.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
).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
.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).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
.i<-i+1
aumentamos la variable i
para cambiarnos de página.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()
out
en un dataframe para usar la librería dplyr.fat.
que estén vacíos.parse()
cambia el string 9+14
a una expresión numérica para poder ser evaluada.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()
.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
.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()
.