R语言 从管道(%>%)中的对象提取多个元素的最佳方式

col17t5w  于 2022-12-24  发布在  其他
关注(0)|答案(1)|浏览(112)

我已经有了一个可行的解决方案,但我想知道是否有更好的方法来达到预期的结果。

library(tidyverse)
library(httr2)
library(rvest)

"https://www.finn.no/realestate/homes/search.html?sort=PUBLISHED_DESC" %>% 
  request() %>%  
  req_perform() %>% 
  resp_body_html() %>% 
  html_elements(".list:nth-child(13) label")

我希望在同一管道中同时提取text及其属性for

element %>% 
  html_text2()

element %>% 
  html_attr("for")

tibble(
  area = element %>% 
    html_text2(), 
  area_code = element %>% 
    html_attr("for")
)

# A tibble: 11 × 2
   area                         area_code       
   <chr>                        <chr>           
 1 Agder (1 748)                location-0.22042
 2 Innlandet (1 967)            location-0.22034
 3 Møre og Romsdal (1 314)      location-0.20015
 4 Nordland (974)               location-0.20018
 5 Oslo (1 622)                 location-0.20061
 6 Rogaland (2 632)             location-0.20012
 7 Troms og Finnmark (1 167)    location-0.22054
 8 Trøndelag (2 334)            location-0.20016
 9 Vestfold og Telemark (2 016) location-0.22038
10 Vestland (2 595)             location-0.22046
11 Viken (7 198)                location-0.22030

我设法在一个管道中做到这一点的一种方法(这样说对吗?)如下所示:

"https://www.finn.no/realestate/homes/search.html?sort=PUBLISHED_DESC" %>% 
  request() %>%  
  req_perform() %>% 
  resp_body_html() %>% 
  html_elements(".list:nth-child(13) label") %>% 
  map_dfr(~ tibble(
    area = .x %>% html_text2(), 
    area_code = .x %>% html_attr("for")
  ))

这产生了一个平均计算时间约0.17-0.2秒。我想优化的代码,因为我将从这个网站刮了很多网页。有没有更好的实现这一点?
我使用包tictoc进行了基准测试

jq6vz3qz

jq6vz3qz1#

因为你已经有一个列表Map每个项目到一个tibble是overkill和计算昂贵的,你可以使用一个apply系列功能(例如lapply)代替这列表和创建这 Dataframe 以后.这将是大约. 3倍快

library(tidyr)
library(httr2)
library(rvest)
library(purrr)
library(microbenchmark)

# I download the data once and store into obj "elements" because i dont want to ddos the website
"https://www.finn.no/realestate/homes/search.html?sort=PUBLISHED_DESC" %>% 
  request() %>%  
  req_perform() %>% 
  resp_body_html() %>% 
  html_elements(".list:nth-child(13) label") -> elements
microbenchmark(

  # lapply
  elements %>% 
    lapply(., \(x) c("area" = html_text2(x),
                     "area_code" = html_attr(x,"for"))
    ) %>% 
    do.call(rbind,.)
  ,
  ## map
  elements %>% 
    map_dfr(~ tibble(
      area = .x %>% html_text2(), 
      area_code = .x %>% html_attr("for")
    ))
  ,times= 500L
)

      min        lq     mean    median        uq      max neval cld
  3.836963  3.999723  4.46171  4.116454  4.315466 15.41846   500  a 
 11.863318 12.375467 13.20117 12.653064 13.049080 23.48040   500   b

相关问题