Как периодически печатать результаты при применении функции к большому набору данных в R? - PullRequest
0 голосов
/ 23 апреля 2019

Я пытаюсь собрать несколько разных деталей из большого количества URL (35000).Я определил несколько функций, используя рабочий процесс rvest, и я использую map, чтобы применить каждую функцию к каждому URL, создавая тиббл непосредственно из функций.Моя проблема заключается в том, что из-за того, что существует так много URL-адресов, для выполнения всего этого требуется очень много времени, и я не могу придумать способ сохранить результаты по ходу работы (если я не сделаю это циклом, что я считаю дажемедленнее).

Единственный способ обойти это - сопоставить куски URL-адресов и соответствующим образом заполнить тиббл.Но этот код действительно неэффективен и требует, чтобы я вручную вводил много чисел снова и снова.

library(rvest); library(tidyverse)

#define function to scrape webdata
##i actually have multiple functions for each css tag i want, and create a tibble column for each one

get_web_info <- function(url) {
  read_html(url) %>%
  html_nodes("h3:nth-of-type(1)") %>%
  html_text()
}

#create tibble scraping the first 500 urls 
##only scrape the first 500 because otherwise there's no output until all 35000 urls are done, which takes more than a day

scraped <- tibble(
  web_info = map(url_vector[1:500], possibly(get_web_info, otherwise = NULL)),
  original_url = url_vector[1:500]
)

#fill in the next 500 rows of the tibble by scraping the next 500 urls
##i would have to copy and paste the code below, manually changing which rows i'm filling in and mapping 

scraped$web_info[500:1000] <- map(url_vector[500:1000], possibly(get_web_info, otherwise = NULL))

Приведенный выше код технически работает, но я знаю, что он очень неэффективен и подвержен ошибкам (особеннокак у меня на самом деле есть 4 функции, и я буду делать выше 4 раза).

Сохранение результатов сопоставления функций по большому набору данных должно быть распространенной проблемой, но я просто не могу найти что-нибудь о том, как это решается.

1 Ответ

0 голосов
/ 23 апреля 2019

Было некоторое обсуждение добавления индикаторов на карту, но я не думаю, что это реализовано. В теме вопроса , однако, jtrecenti опубликовал некоторый код, который использует пакет progress для добавления индикатора выполнения к map.Пример ниже работает, но я не уверен, что он будет работать с вашим кодом:

progressively <- function(.f, .n, ...) {
  pb <- progress::progress_bar$new(total = .n, ...)
  function(...) {
    pb$tick()
    .f(...)
  }
}

input <- 1:5
fun <- function(x) {
  Sys.sleep(.2)
  sample(x)
}
progress_fun <- progressively(fun, length(input))
purrr::map(input, progress_fun)

Это показывает индикатор выполнения во время работы, а затем возвращает:

[[1]]                                                                                               
[1] 1

[[2]]
[1] 1 2

[[3]]
[1] 3 1 2

[[4]]
[1] 2 1 3 4

[[5]]
[1] 5 1 4 3 2
...