#r #web-scraping #xml-parsing
#r #очистка веб-страниц #синтаксический анализ xml
Вопрос:
Я пытаюсь объединить HTML-таблицы данных в единый фрейм данных и ищу элегантное решение. Существует 255 таблиц, а URL-адреса различаются двумя переменными: годом и округом Олдермена. Я знаю, что должен быть способ использовать циклы for или что-то в этом роде, но я в тупике.
Я успешно импортировал данные, прочитав каждую таблицу с помощью отдельной строки кода, но в результате для каждой таблицы получается строка, и снова получается 255 таблиц.
library(XML)
data <- bind_rows(readHTMLTable("http://assessments.milwaukee.gov/SalesData/2018_RVS_Dist14.htm", skip.rows=1),
readHTMLTable("http://assessments.milwaukee.gov/SalesData/2017_RVS_Dist14.htm", skip.rows=1),
readHTMLTable("http://assessments.milwaukee.gov/SalesData/2016_RVS_Dist14.htm", skip.rows=1),
readHTMLTable("http://assessments.milwaukee.gov/SalesData/2015_RVS_Dist14.htm", skip.rows=1),
В идеале я мог бы использовать for
цикл или что-то в этом роде, чтобы мне не приходилось вручную кодировать readHTMLTable
функцию для каждой таблицы.
Ответ №1:
Вы могли бы попробовать создать вектор, содержащий все URL, которые вы хотите очистить, а затем выполнить итерацию по этим входным данным, используя for
цикл:
url1 <- "http://assessments.milwaukee.gov/SalesData/"
url2 <- "_RVS_Dist"
years <- c(2015:2018)
dist <- c(1:15)
urls <- apply(expand.grid(paste0(url1, years), paste0(url2, dist)), 1, paste, collapse="")
data <- NULL
for (url in urls) {
df <- readHTMLTable(url)
data <- rbind(data, df)
}
Комментарии:
1. Спасибо за ваш ответ. Проблема в том, что мне все еще приходится записывать все URL-адреса — я ищу решение, которое автоматизирует итерацию URL-адресов.
2. @Pecners Я дал вам возможность генерировать URL-адреса для всех лет и районов.
Ответ №2:
Мы можем использовать map_dfr
из purrr
пакета (части tidyverse
) пакета, чтобы применить readHTMLTable
функцию к URL. Ключ в том, чтобы определить часть, которая отличается от каждого URL. В этом случае 2015:2018
изменено единственное, поэтому мы можем сконструировать URL с помощью paste0
. map_dfr
автоматически объединило бы все фреймы данных, чтобы вернуть один объединенный фрейм данных. dat
является конечным результатом.
library(tidyverse)
library(XML)
dat <- map_dfr(2015:2018,
~readHTMLTable(paste0("http://assessments.milwaukee.gov/SalesData/",
.x,
"_RVS_Dist14.htm"), skip.rows = 1)[[1]])
Обновить
Вот способ расширить комбинацию между годом и числами, а затем загрузить данные с помощью map2_dfr
.
url <- expand.grid(Year = 2002:2018, Number = 1:15)
dat <- map2_dfr(url$Year, url$Number,
~readHTMLTable(paste0("http://assessments.milwaukee.gov/SalesData/",
.x,
"_RVS_Dist",
.y,
".htm"), skip.rows = 1)[[1]])
Комментарии:
1. Спасибо за ваш ответ. Это работает годами, но район также варьируется, начиная с 1: 15 («14» в URL). Могу ли я использовать этот метод в течение 2002: 2018 годов для районов в диапазоне 1: 15?
2. Передайте районы в качестве второго аргумента с помощью
map2_dfr(arg1, arg2, fun)
. Обратитесь к нему, используя,.y
где это уместно, внутриpaste
выше, и все готово