【问题标题】:lapply on list of xml objectslapply 在 xml 对象列表上
【发布时间】:2016-09-08 05:18:42
【问题描述】:

这是我第一次发帖,如有错误请见谅

我正在尝试从 pubmed 读取 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。确切的错误调用是:

UseMethod("xpathApply") 中的错误:没有适用的方法 'xpathApply' 应用于“list”类的对象

我推测 lapply 用 [i] 的等价物调用列表子集,而我需要的是 [[i]]。有没有解决的办法?还是我必须考虑一些其他规则来重写?

我愿意重写(这只是我正在做的一些玩笑)但是这个问题看起来很有趣,希望你能提供帮助!

【问题讨论】:

    标签: xml r subset lapply


    【解决方案1】:

    在处理 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 命令将出错,并且需要一些额外的工作才能正确解析文件。

    【讨论】:

    • 非常感谢!将探索这个包,看起来它会解决我的直接问题......但是还有没有办法解决我似乎遇到的更普遍的 lapply 问题?我不确定这是否会发生,除非有人使用这种特殊结构......
    • xml_nodes 将返回一个向量,其中包含具有该标记的所有节点。如果结构一致,则不需要使用 lapply。有关示例,请参阅与 rvest 和 xml2 包相关的文档。
    【解决方案2】:

    这将有助于显示产生错误的代码,但您可以尝试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>
    

    【讨论】:

      猜你喜欢
      • 2013-02-19
      • 2020-06-05
      • 2020-12-01
      • 2013-02-16
      • 2017-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多