R Создайте фрейм данных на основе нескольких названных REST-URL. - PullRequest
0 голосов
/ 15 мая 2018

надеюсь, что вы мне поможете.

У меня есть следующий случай:

Я хочу вызвать REST URL.Этот URL-адрес ограничен до макс.количество строк.Поэтому я написал функцию, которая дает мне общее количество вызовов.

Затем я определил различные URL-адреса REST, которые я должен вызвать.Они различаются по номеру страницы.В моем примере у меня будет 9 разных REST URL, поэтому page-num = 1, page-num = 2, ..., page-num = 9

Мне нужно вызвать все 9 REST URL, чтобы получитьцелые данные.

# Rowcount of the REST URL
rowcount <- readHTMLTable(getURL("https://apirest/html/getRowCount&max-results=10000&apikey=123"),
                          stringAsFactors = FALSE, header = FALSE, which = 1, colClasses = c("character","integer"))

# Number of needed Calls of the Rest URL
Calls <- round(as.numeric(as.character(rowcount[,2]))/10000+1)

# Output of different REST URLS
DfCall<-as.data.frame(matrix(NA),nrow=Calls)
for(i in 1:Calls){
  DfCall[i,]<-paste0("https://apirest&max-results=10000&page-num=",i,"&apikey=123")
}

Пока все хорошо.

Но я не могу найти подходящий метод, который позволил бы мне вызывать все 9 URL-адресов REST и связывать их вместе с одним "фрейм основных данных (строка за строкой).

Пожалуйста, прости меня, но я не могу показывать весь REST URL из-за конфиденциальности данных.

Спасибо за любую помощь!

С наилучшими пожеланиями

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Я пробовал цикл for, но это не работает. Проблема в том, что Result2 всегда перезаписывается последней страницей:

for(i in 1:nrow(DfCall)){

    #API call execution
    APIResults<-readHTMLTable(getURL(DfCall[i,]),
                              stringAsFactors = FALSE, header = TRUE, which = 1, colClasses = c("character","character","integer"))

    #Storage of the results in a data frame
    Result2<-rbind(Result,APIResults)

  }

Есть ли способ избежать этой проблемы с перезаписью?

0 голосов
/ 15 мая 2018

Примерно так должно работать:

1:Calls %>% 
     purrr::map(~ paste0("https://apirest&max-results=10000&page-num=",.,"&apikey=123")) %>% 
     purrr::map(~ xml2::read_html(.) %>% rvest::html_table(fill = T)) %>% 
     dplyr::bind_rows()

EDIT: Объясняя, как это работает.

Оператор %>% или pipe работает, передавая (или передавая) результаты вызова функции другой функции, тем самым ограничивая создание временных переменных.

purrr::map берет список и применяет функцию к каждому члену этого списка. Таким образом, для каждого целого числа в 1:Calls он вызывает paste0, создающий строку URL. Помещение ~ перед вашей функцией в вызове map - это немного синтаксического сахара, который позволяет вам использовать заполнитель . в качестве прокси для каждого элемента вашего списка, который передается.

Таким образом, в случае purrr::map(~ paste0("https://apirest&max-results=10000&page-num=",.,"&apikey=123"), . становится каждым целым числом в 1:Calls. Итак, в первой итерации это 1, затем 2 и т. Д.

Когда первый purrr::map сделан, у вас теперь есть список строк URL. Этот список строк затем передается другому purrr::map, функция которого берет строку URL и возвращает dataframe, читая html URL-ссылки и извлекая из нее таблицу. Вы можете заменить этот код любым кодом, который вам нравится, который принимает вашу строку URL в качестве ввода и возвращает желаемое значение dataframe.

После этого шага у вас есть список данных. Этот список затем передается по каналу dplyr::bind_rows(), который объединяет все кадры данных в вашем списке в один кадр данных.

...