将函数应用于R中的大数据集时,如何间歇地打印结果?

时间:2019-04-23 16:27:14

标签: r function web-scraping rvest purrr

我正在尝试从大量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 :(得分:0)

关于在地图上添加进度条已有一些讨论,但我认为它没有实现。 On the issue thread 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