首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用R包xml解析xml/sbml?

如何用R包xml解析xml/sbml?
EN

Stack Overflow用户
提问于 2013-05-02 07:02:14
回答 3查看 1.1K关注 0票数 4

我正在尝试从下面的sbml/xml文件中解析信息

https://dl.dropboxusercontent.com/u/10712588/file.xml

从这段代码

http://search.bioconductor.jp/codes/11172

看起来我可以正常导入这个文件

代码语言:javascript
复制
doc <- xmlTreeParse(filename,ignoreBlanks = TRUE) 

但我无法通过以下方式恢复节点属性

代码语言:javascript
复制
atrr <- xpathApply(doc, "//species[@id]", xmlGetAttr, "id")

代码语言:javascript
复制
xpathApply(doc, "//species", function(n) xmlValue(n[[2]]))

下面是文件的一个节点...

代码语言:javascript
复制
<species id="M_10fthf_m" initialConcentration="1" constant="false" hasOnly
SubstanceUnits="false" name="10-formyltetrahydrofolate(2-)" metaid="_metaM_10fth
f_m" boundaryCondition="false" sboTerm="SBO:0000247" compartment="m">
        <notes>
          <body xmlns="http://www.w3.org/1999/xhtml">
            <p>FORMULA: C20H21N7O7</p>
            <p>CHARGE: -2</p>
            <p>INCHI: InChI=1S/C20H23N7O7/c21-20-25-16-15(18(32)26-20)23-11(7-22
-16)8-27(9-28)12-3-1-10(2-4-12)17(31)24-13(19(33)34)5-6-14(29)30/h1-4,9,11,13,23
H,5-8H2,(H,24,31)(H,29,30)(H,33,34)(H4,21,22,25,26,32)/p-2/t11-,13+/m1/s1</p>
            <p>HEPATONET_1.0_ABBREVIATION: HC00212</p>
            <p>EHMN_ABBREVIATION: C00234</p>
          </body>
        </notes>
        <annotation>
...

我想检索物种节点内的所有信息,有人知道怎么做吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-02 10:45:17

我猜这取决于您说要“检索”物种节点中的所有信息是什么意思,因为检索到的数据可能会被强制转换为任意数量的不同格式。下面假设您希望所有内容都在一个数据框中,其中每一行都是XML文件中的一个物种节点,而列表示不同的信息。

在尝试提取信息时,我通常发现使用列表比使用XML更容易。

代码语言:javascript
复制
doc <- xmlTreeParse(xml_file, ignoreBlanks = TRUE)
doc_list <- xmlToList(doc)

一旦它出现在列表中,你就可以找出物种数据的存储位置:

代码语言:javascript
复制
sapply(x, function(x)unique(names(x)))
[[1]]
NULL

[[2]]
NULL

[[3]]
NULL

[[4]]
[1] "species"

[[5]]
[1] "reaction"

[[6]]
[1] "metaid"

$.attrs
[1] "level"   "version"

因此,您实际上只需要doc_list[[4]]格式的信息。只看一下doc_list[[4]]的第一个组件

代码语言:javascript
复制
str(doc_list[[4]][[1]])
List of 9
 $       : chr "FORMULA: C20H21N7O7"
 $       : chr "CHARGE: -2"
 $       : chr "HEPATONET_1.0_ABBREVIATION: HC00212"
 $       : chr "EHMN_ABBREVIATION: C00234"
 $       : chr "http://identifiers.org/obo.chebi/CHEBI:57454"
 $       : chr "http://identifiers.org/pubchem.compound/C00234"
 $       : chr "http://identifiers.org/hmdb/HMDB00972"
 $       : Named chr "#_metaM_10fthf_c"
  ..- attr(*, "names")= chr "about"
 $ .attrs: Named chr [1:9] "M_10fthf_c" "1" "false" "false" ...
  ..- attr(*, "names")= chr [1:9] "id" "initialConcentration" "constant" "hasOnlySubstanceUnits" ...

因此,您拥有包含在前八个列表中的信息,以及包含在属性中的信息。

获取属性信息很容易,因为它已经命名了。下面将属性信息格式化为每个节点的数据帧:

代码语言:javascript
复制
doc_attrs <- lapply(doc_list[[4]], function(x) {
  x <- unlist(x[names(x) == ".attrs"])
  col_names <- gsub(".attrs.", "", names(x))
  x <- data.frame(matrix(x, nrow = 1), stringsAsFactors = FALSE)
  colnames(x) <- col_names
  x
})

一些节点似乎没有属性信息,因此返回了空的数据帧。这导致了后来的问题,所以我在它们的位置创建了NAs的数据帧:

代码语言:javascript
复制
doc_attrs_cols <- unique(unlist(sapply(doc_attrs, colnames)))
doc_attrs[sapply(doc_attrs, length) == 0] <- 
  lapply(doc_attrs[sapply(doc_attrs, length) == 0], function(x) {
    df <- data.frame(matrix(rep(NA, length(doc_attrs_cols)), nrow = 1))
    colnames(df) <- doc_attrs_cols
    df
  })

在提取非属性数据时,变量的名称和值通常包含在同一个字符串中。我最初试图想出一个正则表达式来提取名称,但它们的格式都如此不同,以至于我放弃了,只是确定了这个特定数据集中的所有可能性:

代码语言:javascript
复制
flags <- c("FORMULA:", "CHARGE:", "HEPATONET_1.0_ABBREVIATION:", 
  "EHMN_ABBREVIATION:", "obo.chebi/CHEBI:", "pubchem.compound/", "hmdb/HMDB",  
  "INCHI: ", "kegg.compound/", "kegg.genes/", "uniprot/", "drugbank/")

此外,有时非属性信息只是作为值的列表保存,就像我在上面显示的节点中一样,而有时它包含在“注释”和“注释”子列表中,因此我必须包括一条if else语句以使其更一致。

代码语言:javascript
复制
doc_info <- lapply(doc_list[[4]], function(x) {
  if(any(names(x) != ".attrs" & names(x) != "")) {
    names(x)[names(x) != ".attrs"] <- ""
    x <- unlist(do.call("c", as.list(x[names(x) != ".attrs"])))
  } else {
  x <- unlist(x[names(x) != ".attrs"])
  }
  x <- gsub("http://identifiers.org/", "", x)
  need_names <- names(x) == ""
  names(x)[need_names] <- gsub(paste0("(", paste0(flags, collapse = "|"), ").+"), "\\1", x[need_names], perl = TRUE)
  #names(x) <- gsub("\\s+", "", names(x))
  x[need_names] <- gsub(paste0("(", paste0(flags, collapse = "|"), ")(.+)"), "\\2", x[need_names], perl = TRUE)
  col_names <- names(x)
  x <- data.frame(matrix(x, nrow = 1), stringsAsFactors = FALSE)
  colnames(x) <- col_names
  x
})

要将所有内容整合到一个数据框架中,我建议使用plyr包的rbind.fill

代码语言:javascript
复制
require(plyr)

doc_info <- do.call("rbind.fill", doc_info)
doc_attrs <- do.call("rbind.fill", doc_attrs)

doc_all <- cbind(doc_info, doc_attrs)


dim(doc_all)
[1] 3972   22

colnames(doc_all)
 [1] "FORMULA:"                    "CHARGE:"                     "HEPATONET_1.0_ABBREVIATION:" "EHMN_ABBREVIATION:"         
 [5] "obo.chebi/CHEBI:"            "pubchem.compound/"           "hmdb/HMDB"                   "about"                      
 [9] "INCHI: "                     "kegg.compound/"              "kegg.genes/"                 "uniprot/"                   
[13] "drugbank/"                   "id"                          "initialConcentration"        "constant"                   
[17] "hasOnlySubstanceUnits"       "name"                        "metaid"                      "boundaryCondition"          
[21] "sboTerm"                     "compartment"       
票数 2
EN

Stack Overflow用户

发布于 2013-05-02 18:36:56

存在一个SBML解析库libSBML (http://sbml.org/Software/libSBML)。

这包括一个到R的绑定,它允许在R中使用类似于

代码语言:javascript
复制
document  = readSBML(filename);

errors = SBMLErrorLog_getNumFailsWithSeverity(
            SBMLDocument_getErrorLog(document), 
            enumToInteger("LIBSBML_SEV_ERROR", "_XMLErrorSeverity_t")
         );


if (errors > 0) {
  cat("Encountered the following SBML errors:\n");
  SBMLDocument_printErrors(document);
  q(status=1);
}

model = SBMLDocument_getModel(document);

if (is.null(model)) {
  cat("No model present.\n");
  q(status=1);
}

species = Model_getSpecies(model, index_of_species);

id = Species_getId(species);
conc = Species_getInitialConcentration(species)

每个可能的属性都有一个Species_get(NameOfAttribute)函数;还有Species_isSet(NameOfAttribute)、Species_set(NameOfAttribute)和Species_unset(NameOfAttribute)。

该API类似于与任何SBML元素交互。

libSBML发行版包括R安装程序,这些安装程序可从

http://sourceforge.net/projects/sbml/files/libsbml/5.8.0/stable

导航到您选择的操作系统和体系结构对应的R_interface子目录。

libSBML的源代码发行版包含一个examples/r目录,其中包含许多在R环境中使用libSBML与SBML进行交互的示例。

票数 4
EN

Stack Overflow用户

发布于 2013-05-02 09:43:42

作为部分答案,文档使用了名称空间,而‘种’是'id‘名称空间的一部分。所以

代码语言:javascript
复制
> xpathSApply(doc, "//id:species", xmlGetAttr, "id", namespaces="id")
 [1] "M_10fthf_c"   "M_10fthf_m"   "M_13dampp_c"  "M_h2o_c"      "M_o2_c"      
 [6] "M_bamppald_c" "M_h2o2_c"     "M_nh4_c"      "M_h_m"        "M_nadph_m" 
 ...  

id:speciesnamespaces="id"与您上面所演示的有所不同。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16327822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档