Re: [問題]用data.frame中的某個column擷取網頁資料

作者: andrew43 (討厭有好心推文後刪文者)   2014-02-04 05:32:37
假設你有一個 data frame 叫 x,其中有一個欄叫 id。因此,
myURL <- paste("http://www.ncbi.nlm.nih.gov/gene/", x$id, sep="")
就是所有要去拿取的完整網址。
以下一個為你設計的 function 先餵 R 吃下去。
它可以一次拿取一個網頁裡你要的資料。
myfunc <- function(myURL){
con <- url(myURL)
txt <- scan(con, what="character")
close(con)
txt1 <- paste(txt, sep="", collapse=" ")
pattern <- "<dt>Summary</dt> <dd>[[:print:]]+</dd>"
re <- regexpr(pattern, txt1)
start <- re[1]
end <- start[1] + attr(regexpr(pattern, txt1),"match.length") - 1
return(substr(txt1, start + 22, end - 5))
}
再試試看
myfunc("http://www.ncbi.nlm.nih.gov/gene/2597")
的結果是不是你要的。有需要的話自己修一下。
可以的話,就用迴圈把 myURL 一個一個丟給 myfunc()
results <- list()
for(i in 1:length(myURL)){
results[[i]] <- myfunc(myURL[i])
}
這樣應該就好了。
: 各位好
: 我需要下載數百個基因的資料
: 網址的格式是:
: http://www.ncbi.nlm.nih.gov/gene/XXXX
: 其中XXXX是這些基因的ID(可能是四個數字或更多)
: 比如GAPDH ID是2597
: 那連結就是:http://www.ncbi.nlm.nih.gov/gene/2597
: 如果我的data frame中有一個column是這些IDs
: 我應該如何寫出簡單的R scripts來擷取這些網頁中的"Summary"中的敘述
: 並加到原本data.frame中相對應rows 形成一個新的column (不包括"Summary"這字本身)
: 例如對GAPDH而言就是
: "This gene encodes ... variants. [provided by RefSeq, Jan 2014]"
: 我想應該是用Rcurl跟grep
: 但因為完全外行
: 不知道如何逐個ID數值加到Rcurl網址的最後
: 再將下載的網頁以grep搜尋到的strings加到對應的rows裡
: 這樣的問題很不專業
: 如果有任何的提示都歡迎
: 謝謝各位專家
: [程式範例]:
: [關鍵字]: R 網頁下載 部分擷取
作者: kusoayan (Bert)   2014-02-04 12:28:00
我想問一下,如果用 XML 或 selectr 這兩個套件會有什麼明顯差異或 drawbacks 嗎?
作者: stinky (stinky)   2014-02-04 12:44:00
太感謝了! 我回辦公室馬上試試看
作者: Wush978 (拒看低質媒體)   2014-02-04 12:47:00
我只用過XML, 目前沒感受到什麼明顯的drawback真的說的話,就是處理中文會遇到的編碼問題吧
作者: maninblue   2014-02-04 14:21:00
推~
作者: summitstudio (第凡斯米德費爾德)   2014-02-04 15:02:00
推範例碼!
作者: andrew43 (討厭有好心推文後刪文者)   2014-02-04 20:40:00
這篇的程式碼都只用到R內建的function。至於XML和selectr這些套件怎麼用我並不了解,但我猜可能可以在截取網頁內容時會更方便。其實仔細看我的程式碼,只是很簡單的字串處理而已,對付格式一致的大量網頁應該夠用了。
作者: stinky (stinky)   2014-02-05 13:20:00
謝謝andrew43 非常好用 稍修改後也可運用在其他databases我還有兩個小問題想請教 因為抓取時經常會斷線是否有辦法讓它失敗時自動重複嘗試幾次?又或者讓我指定我可以選擇讓程式從某個row繼續抓?補充一下 因為我想把資料新增在最後一個column所以試了 x$Summary[[i]] <- myfunc(myURL[i]) 有用
作者: andrew43 (討厭有好心推文後刪文者)   2014-02-05 13:53:00
重複嘗試可能可以採取 try() 之類錯誤處理的方式解決。至於一次從特定位置開始抓可能沒辦法。對方server可能會把你判斷為不友善的client,不要做得太暴力,或是在loop裡放一些延遲功能。
作者: stinky (stinky)   2014-02-05 14:25:00
我試將for(i in 1:length(myURL)){ 中的1改成其他數字作為續傳起點 結果可以從斷的資料點繼續 太感謝你了!
作者: andrew43 (討厭有好心推文後刪文者)   2014-02-06 16:34:00
喔,我以為你是指從一個網頁的特定位置續傳(這我辦不到

Links booklink

Contact Us: admin [ a t ] ucptt.com