2016-05-12 35 views
3

這是我在這裏的第一篇文章,所以請原諒任何錯誤WRT發帖準則lapply基於XML的對象列表

我試圖從考研中的XML數據讀取,以提取作者的隸屬關係數據

每個條目包含了一組像這樣的節點:

<AuthorList> 
      <Author> 
      <LastName>Serra-Blasco</LastName> 
      <ForeName>Maria</ForeName> 
      <Initials>M</Initials> 
      <AffiliationInfo> 
       <Affiliation>Department of Psychiatry, Hospital de la Santa Creu i Sant Pau, Biomedical Research Institute Sant Pau (IIB Sant Pau), Universitat Autònoma de Barcelona (UAB), Centro de Investigación Biomédica en Red de Salud Mental (CIBERSAM), Barcelona, Catalonia, Spain.</Affiliation> 
      </AffiliationInfo> 
      </Author> 
      ... 

我想與包含在一行中的每個作者的姓名和聯繫一個數據幀就結了。

我試圖使用xpathSApply來解析讀取「// Author」的節點,並以xml節點列表結束。

進一步的解析被證明是一個問題:我已經編寫了代碼來處理這個列表中的一個單獨的元素;

爲例如,如果該列表是authorlist

我可以使用該功能(在元件內使用xpathSApply)

提取適當陣列,用於authorlist[[1]]但是,當我嘗試解決此功能lapply包裹,它給我一個錯誤,說它不能在列表上執行xpathApply。確切的錯誤電話是:適用於類的「名單」的對象

我猜測,lapply調用的 「xpathApply」沒有適用的方法:

錯誤UseMethod(「xpathApply」)列出與[i]等價的子集,而我需要的是[[i]]。有沒有解決的辦法?或者我會不得不重寫一些其他規則?

我打開重寫(這只是一些愚蠢的事情,我正在做),但這個問題似乎很有趣,希望你能幫助!

回答

2

我更喜歡在使用html/xml文件時使用軟件包rvest。根據您的簡單的例子:

library(rvest) 
myxml<-read_xml("author.xml") 

lastname<-xml_text(xml_nodes(myxml,"LastName")) 
firstname<-xml_text(xml_nodes(myxml,"ForeName")) 
affiliation<-xml_text(xml_nodes(myxml,"Affiliation")) 
df<-data.frame(firstname, lastname, affiliation) 

如果XML文件的結構發生變化,然後再打電話給data.frame命令將錯誤和一些額外的工作,需要正確解析文件。

+0

非常感謝!將探索這個包,看起來像它會解決我的直接問題... 但也有一種解決方法,我似乎遇到了更普遍的lapply問題?我不確定是否會發生這種情況,除非有人正在使用此特定結構... –

+1

xml_nodes將返回帶有該標記的所有節點的向量。如果結構一致,則不需要使用lapply。有關示例,請參閱與rvest和xml2軟件包相關的文檔。 – Dave2e

1

這將有助於顯示你的代碼產生錯誤,但你可以嘗試xmlToDataFrame

url <- "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=23620451&rettype=XML" 
doc <- xmlParse(url) 

xmlToDataFrame(doc["//Author"]) 
      LastName ForeName Initials     AffiliationInfo 
1  Serra-Blasco Maria  M Department of Psychiatry...Spain. 
2   Portella Maria J  MJ        <NA> 
3  Gómez-Ansón Beatriz  B        <NA> 
... 

如果您得到的具有零個或多個標籤節點,我通常會創建一個函數來設置缺少的標記,以NA以及用於連接多個標籤的分隔符。

authors <- getNodeSet(doc, "//Author") 

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

last <- sapply(authors, xpath2, ".//LastName") 
aff <- sapply(authors, xpath2, ".//Affiliation") 
data.frame(last, aff) 
       last        aff 
1  Serra-Blasco Department of Psychiatry...Spain. 
2   Portella        <NA> 
3  Gómez-Ansón        <NA> 
相關問題