2017-04-04 26 views
0

by_rowrowwiseの違いは誰にも分かりますか?私は3つのシンプルなウェブサイトを掻き集めようとしています。どちらのアプローチでも働くことができないので、私がちょうど使用しているかわかりません。purr/dplyrが間違っています。by_rowと行ごとの繰り返し

データ:

dplyr approach: 
    table %>% 
     rowwise() %>% 
     read_html() %>% 
     extract2(2) %>% 
     html_nodes("#_brand4 span") %>% 
     html_text() 

ゴロゴロアプローチ:すべてのURL(または列)の場合

structure(list(beer_brewerid = c("8481", "3228", "10325"), link = 
c("https://www.ratebeer.com/beer/8481/", "https://www.ratebeer.com/beer/3228/", "https://www.ratebeer.com/beer/10325/"), scrapedname = c("", "", "")), .Names = c("beer_brewerid", "link", "scrapedname"), row.names = c(NA, 3L), class = "data.frame") 

、私は次の関数を使用してWebページをこすりしたい

#Apply function to each row 
table %>% 
    by_row(..f = parserows(), collate = c("rows"), .to = "scrapedname") 

#Takes in row 
parserows = function(){ 
     read_html() %>% 
     extract2(., 2) %>% 
     html_nodes("#_brand4 span") %>% 
     html_text() 
} 

purrのアプローチでは、xが省略されていない場合にエラーが発生します。値が行番号から来るべきではありませんか?さもなければ、行番号がどこにあるかを指定するforループを書くでしょう。このmagrittr配管を使用して

は、私は私のcode.Soでタイムアウトエラーを取得しておいてください。

  1. 私のDF内のすべての要素を反復処理するためにゴロゴロ/ dplyrを使用しているとき、私はタイムアウトエラーを回避するにはどうすればよいですか?もしそうなら、私はtrycatch、または何らかのエラー処理メカニズムを使用して、エラーが発生したときにそれを捕捉することを検討すべきでしょうか?

  2. rowwise/by_rowは本当にこのタスクの対象ですか?私は、これらの関数が行内のすべての要素に対して反復することを意図していると考えています。これは正確に私がこの問題を解決しようとしているものではありません。ありがとう。ここで

    output = table$link %>% 
    extract() %>% 
    map(read_html) %>% 
    html_nodes(row,"#_brand4 span") %>% 
    html_text(row) 
    
+0

あなたのリンクをベクトルとして扱い、その上にマップします: 'my_dat $ link%>% map(read_html)%>%...' –

+0

私はたくさんのリンクを持っていて、私は時間切れのエラーを取得し続けます。更新されたコードをご覧ください。 – petergensler

+0

'' purrr :: safeely''と '' purrr :: transpose''を見てください。 –

答えて

3

@Thomas Kさんの提案は、次のようになり何です:のみpurrr

まず:

library(purrr) 
library(dplyr) 
library(httr) 
library(xml2) 
library(rvest) 

table$link %>% 
    purrr::set_names() %>% 
    map(read_html) %>% 
    map(html_node, "#_brand4 span") %>% 
    map(html_text) 

# $`https://www.ratebeer.com/beer/8481/` 
# [1] "Föroya Bjór" 
# 
# $`https://www.ratebeer.com/beer/3228/` 
# [1] "King Brewing Company" 
# 
# $`https://www.ratebeer.com/beer/10325/` 
# [1] "Bavik-De Brabandere" 

html_nodes(複数を使用する必要はありません注意してください)、 html_node(単数)ではなく)。

res <- 
    table %>% 
    mutate(html = map(link, read_html), 
     brand_node = map(html, html_node, "#_brand4 span"), 
     scrapedname = map_chr(brand_node, html_text)) 

htmlbrand_node

を外部ポインタとして保存されているとはありません。あなたがそれらを再利用する必要がある場合には、きちんとしたデータフレームの各HTMLドキュメントを保つことができます

混合dplyr/purrr代替、非常にプリントフレンドリーなので、ここではそれらなしで結果のデータフレームです:タイムアウトの問題のために

select(res, - html, - brand_node) 

# beer_brewerid         link   scrapedname 
# 1   8481 https://www.ratebeer.com/beer/8481/   Föroya Bjór 
# 2   3228 https://www.ratebeer.com/beer/3228/ King Brewing Company 
# 3   10325 https://www.ratebeer.com/beer/10325/ Bavik-De Brabandere 

glimpse(res) 

# Observations: 3 
# Variables: 5 
# $ beer_brewerid <chr> "8481", "3228", "10325" 
# $ link   <chr> "https://www.ratebeer.com/beer/8481/", "https://www.ratebeer.com/beer/3228/", "https://www.ratebeer.com/beer/10325/" 
# $ scrapedname <chr> "Föroya Bjór", "King Brewing Company", "Bavik-De Brabandere" 
# $ html   <list> [<html lang="en">, <html lang="en">, <html lang="en">] 
# $ brand_node <list> [<span itemprop="name">, <span itemprop="name">, <span itemprop="name">] 

、あなたは、また@Thomas Kさんのコメントにつき、単純にread_htmlをラップすることができ(実際tryCatchに代わるものです)safely()またはpossibly()

safe_read_html <- possibly(read_html, otherwise = read_html("<html></html>")) 

しかし、あなたは、サーバー上であまりにもハードつもりだ(可能な)現実的な問題に対処するために、私はあなたをすることができますhttr::RETRY()を示唆している、よく、再試行、「指数バックオフ時間」で:

safe_retry_read_html <- possibly(~ read_html(RETRY("GET", url = .x)), otherwise = read_html("<html></html>")) 

こする良い習慣は、サーバー上の実際の優しい行くことですので、あなたは手動でも例えばSys.sleep(1 + runif(1))で、各要求の前にタイムオフセットを追加することができます。

table$link %>% 
    c("https://www.wrong-url.foobar") %>% 
    purrr::set_names() %>% 
    map(~ { 
    Sys.sleep(1 + runif(1)) 
    safe_retry_read_html(.x) 
    }) %>% 
    map(html_node, "#_brand4 span") %>% 
    map_chr(html_text) 

# https://www.ratebeer.com/beer/8481/ https://www.ratebeer.com/beer/3228/ 
#      "Föroya Bjór"    "King Brewing Company" 
# https://www.ratebeer.com/beer/10325/   https://www.wrong-url.foobar 
#    "Bavik-De Brabandere"         NA 

最後に、by_row()/rowwise()についてのあなたの個別の質問があります。
まず、by_rowpurrrの開発版から削除され、それはとにかく廃止予定だ別のパッケージ、purrrlyr、に移動し、することをお勧めしますされていることに注意してください「の組み合わせを使用します。tidyr::nest()を、dplyr::mutate(); purrr::map()

help("rowwise")から、rowwiseは、ほとんどが "リスト変数を作成するときにdo()の結果に使用される"ことを意味します。

だから、どちらも「本当にこの仕事には意味がありません」といっても、余計なものになるでしょう。

+0

このような詳細な説明をいただきありがとうございます。私が以前に気づいたように、行方法は私が笑いたいと思っていたものではありません。私はおそらく使用するいくつかのソリューションを見ましたが、それは幾分スケッチで見えました。私は通過する必要がある約7,000のURLを持っているので、これは非常に有用です。 – petergensler

+0

magrittrパイプを使用して複数のマップコマンドを連鎖する必要がありますか?パイプでマップを使うというのは本当に好きですが、マップコマンドで〜{}が何をしているのか分かりません。 – petergensler

+0

'map()'のようにチェーンしたり、 。それは私が推測する味の問題です。チルダ '〜'の意味については、例えば、「purrr」ビネットを参照してください。本質的には汎用的な式の表記 –

関連する問題