R - 迭代xpathApply问题

时间:2017-03-28 09:56:47

标签: r xml

这是我在SE上的第一篇文章,但我经常使用它!

我一直很难尝试使用R.

从PMC XML文件中提取信息

我一直在尝试复制this代码,但发现每篇文章都没有遍历文章集并提取项目,而multiple_papers函数返回每篇文章的整个列表(在此示例中共有6篇文章)并且列表被打印36次)。

Sample XML File

library(XML)

SearchResults <- xmlRoot(xmlTreeParse('PMC_SE_Examp.xml', useInternal=TRUE))

parse_title <- function(paper){
    print (xpathApply(paper, '//title-group/article-title', xmlValue))
}

parse_multiple_papers <-function(papers){
    thisPaper <- xpathApply(papers, "//pmc-articleset/*", parse_title)
}


x <- parse_multiple_papers(SearchResults)

我不能为我的生活弄清楚为什么会这样,并想知道是否有人可以为我阐明这一点?非常感谢提前!

1 个答案:

答案 0 :(得分:0)

花了几个小时回顾我的步骤并查阅原始代码后,我现在设法得到了我正在寻找的行为。我的目的是从一组中的每篇论文中提取作者,标题,PMID和摘要。以下代码执行此操作。我非常欢迎任何反馈。

SearchResults<- xmlRoot(xmlParse('PMC_SE_Examp.xml')) #load file and set root

parse_author <- function(author){ #lists separate names. Not sure how to deal with multiple names yet so I used the first 
  fn  <- xmlValue(author[["given-names"]])
  ln  <- xmlValue(author[["surname"]])
  if (is.null(list(forname=fn, lastname=ln))){
    list(forname=NA, lastname=NA)}

  else{list(forname=fn, lastname=ln)}
}


parse_paper <- function(paper){
  author_info <- xpathApply(paper, ".//contrib-group/contrib/name", parse_author)
  title_text <- unlist(xpathApply(paper, ".//title-group/article-title", xmlValue))
  if(is.null(title_text)){title_text=NA} #for incomplete entries
  abstract_text <- unlist(xpathApply(paper, ".//abstract", xmlValue))
  if(is.null(abstract_text)){abstract_text=NA}
  pmid <-xpathSApply(paper, ".//article-meta/article-id[@pub-id-type = 'pmid']", xmlValue)
  if(is.null(pmid)){pmid=NA} #in the original, bind.data.frame is used - doesn't work here, so I create the data frame first and then rbind it
  dat <- data.frame(pid = pmid,aut=author_info[1],tit=title_text,ab=abstract_text)
  res <- rbind(dat)
  res
}

parse_multiple_papers <- function(papers){
 res <- xpathApply(papers, "/pmc-articleset/*", parse_paper)
 do.call(rbind.data.frame, res)
}

z <- parse_multiple_papers(SearchResults)
write.csv(z,"datafile.csv")