2016-12-02 91 views
0

我想創建一個函數,與pubmed API進行交互,以檢索與100個出版物相關的xml文件。然後,我想分別解析xml文件以檢索每個出版物的標題和每個出版物的摘要。我正在使用Rentrez軟件包與api進行交互,併成功檢索了必要的xml文件。我正在使用xml包來解析xml文件,並驗證了Xpath表達式檢索我想要的數據。事實上,我期待從其他領域獲取數據(期刊名稱,網格術語等,但我堅持在這一步這裏)從for循環存儲數據幀中的數據

但是,我還沒有能夠創建一個適當的循環移動將這些數據轉換成數據幀。我收到以下錯誤運行我的代碼:

錯誤$<-.data.frame*tmp*,「摘要」,值=名單(「抽象的文字」): 更換具有1行,數據具有0

當我測試函數接收標題信息(通過刪除表達式來檢索抽象信息),我收到一個空的數據框,但沒有關於我想要的標題的信息,但是沒有錯誤信息然後

如果我執行pubmed_pa​​rsed (「Kandel + Eric」,n = 2),我的目標是從列「ATitle」中的兩個標題的字符向量中接收數據幀(標題:「角色f或在哺乳動物大腦沉默逆轉錄轉座子中的小非編碼RNA「和」ApCPEB4,含有A​​pCPEB的非朊病毒結構域同源物,參與啓動長期促進「)。並且來自兩個摘要的字符矢量相應地出現在「摘要」(摘要的部分:「Piwi相互作用RNA(piRNA),長期以來被認爲僅限於gremlin ...」,「兩種藥理學上不同類型的局部蛋白質合成需要突觸特異性......「)。

library(xml) 
library(rentrez) 
pubmed_parsed <- function(term, n=100){ 
    df <- data.frame(ATitle = character(), JTitle = character(), MeshTerms = character(), Abstract = character(), FAuthor = character(), LAuthor = character(), stringsAsFactors = FALSE) 
    IdList <- entrez_search(db = "pubmed", term = term, retmode = "xml", retmax = n) 
    for (i in 1:n){ 
    XmlFile <- entrez_fetch(db = "pubmed", id=IdList$ids[i], rettype = "xml", retmode = "xml", parsed=TRUE) 
    Parsed <- xmlRoot(XmlFile) 
    df$ATitle[i] <- xpathSApply(Parsed, "/PubmedArticleSet/PubmedArticle/MedlineCitation/Article/Title", xmlValue, simplify = FALSE) 
    df$Abstract[i] <- xpathSApply(Parsed, "/PubmedArticleSet/PubmedArticle/MedlineCitation/Article/Title", xmlValue, simplify = FALSE) 
    } 
    df 
} 
+0

請包括庫報表和其他任何使這種重複性 –

+0

我已經在相應的庫語句添加必要的,我想從一個正確構建「pubmed_pa​​rsed」功能得到什麼的例子。謝謝。 – KevinF

+0

注意:'library(XML)'全部大寫。 R區分大小寫! – Parfait

回答

0

以下是獲取表格和一些建議的一種方法。首先,我將使用網絡歷史記錄選項並將所有結果一起下載,而不是通過下載循環。

ids <- entrez_search(db = "pubmed", term = "Kandel ER", use_history = TRUE) 
ids 
Entrez search result with 502 hits (object contains 20 IDs and a web_history object) 
Search term (as translated): Kandel ER[Author] 

doc <- entrez_fetch(db="pubmed", web_history=ids$web_history, rettype="xml", retmax = 3, parsed=TRUE) 

接下來,獲取文章到一個節點集和查詢,以處理所有缺少和多個標籤。

articles <- getNodeSet(doc, "//PubmedArticle") 
length(articles) 
[1] 3 
articles[[1]] 
<PubmedArticle> 
    <MedlineCitation Status="Publisher" Owner="NLM"> 
    <PMID Version="1">27791114</PMID> 
    <DateCreated> 
    ... 

我通常創建一個函數來添加NAs,如果標籤丟失並使用逗號加入多個標籤。

xpath2 <-function(x, path, fun = xmlValue, ...){ 
     y <- xpathSApply(x, path, fun, ...) 
    ifelse(length(y) == 0, NA, 
     ifelse(length(y) > 1, paste(unlist(y), collapse=", "), y)) 
} 

然後,只需將該函數應用於節點(xpath中的前導點,所以它是相對於該節點)。這會將多個關鍵字組合成以逗號分隔的列表,並將包含缺失關鍵字的文章3的NA包含在內。

sapply(articles, xpath2, ".//Keyword") 
[1] "DNA methylation, behavior, endogenous siRNA, piwi-interacting RNA, transposon" 
[2] "Aplysia, CPEB, CPEB4, Long-term facilitation"         
[3] NA 

大多數XPath的應該工作

sapply(articles, xpath2, ".//PubDate/Year") 
[1] "2016" "2016" "2016" 
sapply(articles, xpath2, ".//ArticleId[@IdType='pmc']") 
[1] "PMC5111663" "PMC5075418" NA 

您還可以使用xmlGetAttr如果需要

sapply(articles, xpath2, ".//Article", xmlGetAttr, "PubModel") 
[1] "Print-Electronic" "Electronic"  "Electronic" 

最後,創建一個data.frame

data.frame( 
    ATitle = sapply(articles, xpath2, ".//ArticleTitle"), 
    JTitle = sapply(articles, xpath2, ".//Journal/Title"), 
Keywords = sapply(articles, xpath2, ".//Keyword"), 
Authors = sapply(articles, xpath2, ".//Author/LastName"), 
Abstract = sapply(articles, xpath2, ".//AbstractText")) 

我不是確定我發生了什麼事SH條款,但我只在我下載的幾個示例中看到關鍵字。另外,可能有幾種方法可以獲得第一個和最後一個作者。您可以同時獲得姓氏和姓名縮寫(假設兩者始終存在),並在首字母之前替換逗號以獲取作者字符串。然後將其分割以獲得第一個和最後一個作者,甚至打印下面的前三個。

au <- sapply(articles, xpath2, ".//Author/LastName|.//Author/Initials") 
au <- gsub(",([A-Z]+,?)", "\\1", au) 
authors_etal <- function(x, authors=3, split=", *"){ 
    y <- strsplit(x, split) 
    sapply(y, function(x){ 
     if(length(x) > (authors + 1)) x <- c(x[1:authors], "et al.") 
     paste(x, collapse=", ") 
    }) 
} 

authors_etal(au) 
[1] "Nandi S, Chandramohan D, Fioriti L, et al." 
[2] "Lee SH, Shim J, Cheong YH, et al."   
[3] "Si K, Kandel ER" 
+0

謝謝!基於你的建議,很容易檢索網格術語:MeshTerms = sapply(NodeSet,xpath2,「.//MeshHeading/DescriptorName|//MeshHeading/QualifierName」,xmlGetAttr,「UI」) – KevinF

+0

獲取描述符的向量和限定符,我通常運行第二個查詢來獲取'xmlName',然後在限定符前粘貼一個「\」,最後使用這個[answer](http://stackoverflow.com/questions/38364060/paste-一些元素-的混合向量) –