Я очищаю базу данных ASN (http://aviation-safety.net/database/). Я написал код для разбивки по страницам каждого года (1919-2019) и очистки всех соответствующих узлов, кроме фатальных исходов (обозначенных как «толстые»). Selector Gadget сообщает мне, что узел фаталити называется "'#contentcolumnfull :nth-child(5)'". По какой-то причине ".list:nth-child(5)" не работает.
Когда я очищаю #contentcolumnfull :nth-child(5), первый элемент пустой, представленный как "".
Как я могу написать функцию для удаления первого пустого элемента для каждого года/страницы, которая очищена? Просто удалить первый элемент, когда я очищаю одну страницу самостоятельно:
fat <- html_nodes(webpage, '#contentcolumnfull :nth-child(5)')
fat <- html_text(fat)
fat <- fat[-1]
но мне трудно писать в функцию.
У меня также есть второй вопрос относительно даты и времени и форматирования. Данные о моих днях представлены как день-месяц-год. Отсутствует несколько элементов дней и месяцев (пример: ??-??-1985, JAN-??-2004). В идеале я хотел бы преобразовать даты в объект смазки, но я не могу с отсутствующими данными или если я сохраняю только годы.
На данный момент я использовал gsub() и регулярное выражение для очистки данных (удаление «??» и плавающие тире), поэтому у меня есть смешанный набор форматов данных. Однако это затрудняет визуализацию данных. Мысли о передовом опыте?
# Load libraries
library(tidyverse)
library(rvest)
library(xml2)
library(httr)
years <- seq(1919, 2019, by=1)
pages <- c("http://aviation-safety.net/database/dblist.php?Year = ") %>%
paste0(years)
# Leaving out the category, location, operator, etc. nodes for sake of brevity
read_date <- function(url){
az <- read_html(url)
date <- az %>%
html_nodes(".list:nth-child(1)") %>%
html_text() %>%
as_tibble()
}
read_type <- function(url){
az <- read_html(url)
type <- az %>%
html_nodes(".list:nth-child(2)") %>%
html_text() %>%
as_tibble()
}
date <- bind_rows(lapply(pages, read_date))
type <- bind_rows(lapply(pages, read_type))
# Writing to dataframe
aviation_df <- cbind(type, date)
aviation_df <- data.frame(aviation_df)
# Excluding data cleaning
Плохая практика - пинговать одну и ту же страницу более одного раза, чтобы извлечь запрошенную информацию. Вы должны прочитать страницу, извлечь всю необходимую информацию, а затем перейти к следующей странице.
В этом случае все отдельные узлы хранятся в одной главной таблице. Функция rvest html_table()
удобна для преобразования HTML-таблицы во фрейм данных.
library(rvest)
library(dplyr)
years <- seq(2010, 2015, by=1)
pages <- c("http://aviation-safety.net/database/dblist.php?Year = ") %>%
paste0(years)
# Leaving out the category, location, operator, etc. nodes for sake of brevity
read_table <- function(url){
#add delay so that one is not attacking the host server (be polite)
Sys.sleep(0.5)
#read page
page <- read_html(url)
#extract the table out (the data frame is stored in the first element of the list)
answer<-(page %>% html_nodes("table") %>% html_table())[[1]]
#convert the falatities column to character to make a standardize column type
answer$fat. <-as.character(answer$fat.)
answer
}
# Writing to dataframe
aviation_df <- bind_rows(lapply(pages, read_table))
Есть несколько дополнительных столбцов, которые потребуют очистки.
Спасибо! Я ценю совет по настройке sys.sleep, чтобы упростить работу с серверами. eta: Также спасибо за подсказку о очистке всей таблицы. Изначально я собирался очистить только 3 узла, но кажется, что проще взять всю таблицу, чем очистить оттуда.