加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 23:07:09 所属栏目:百科 来源:网络整理
导读:我正在尝试解析下面的sbml / xml文件中的信息 https://dl.dropboxusercontent.com/u/10712588/file.xml 从这段代码 http://search.bioconductor.jp/codes/11172 好像我可以正常导入文件 doc - xmlTreeParse(filename,ignoreBlanks = TRUE) 但我无法通过恢复
我正在尝试解析下面的sbml / xml文件中的信息

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

从这段代码

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

好像我可以正常导入文件

doc <- xmlTreeParse(filename,ignoreBlanks = TRUE)

但我无法通过恢复节点属性

atrr <- xpathApply(doc,"//species[@id]",xmlGetAttr,"id")

要么

xpathApply(doc,"//species",function(n) xmlValue(n[[2]]))

文件的节点如下……

<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>
...

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

解决方法

我想这取决于你说你想要“检索”物种节点中的所有信息时你的意思,因为检索到的数据可以被强制为任意数量的不同格式.以下假设您希望在数据框中全部使用它,其中每一行都是XML文件中的物种节点,而列表示不同的信息.

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

doc <- xmlTreeParse(xml_file,ignoreBlanks = TRUE)
doc_list <- xmlToList(doc)

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

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]]的第一个组件:

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" ...

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

获取属性信息很简单,因为它已经命名.以下格式将属性信息格式化为每个节点的数据框:

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
})

某些节点似乎没有属性信息,因此返回空数据帧.这导致了以后的问题所以我在他们的位置创建了NA的数据框:

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
  })

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

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

此外,有时非属性信息只保留为值列表,如上面显示的节点,而有时它包含在“notes”和“annotation”子列表中,所以我必须包含一个if else语句使事情更加一致.

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("(",")(.+)"),"2",perl = TRUE)
  col_names <- names(x)
  x <- data.frame(matrix(x,stringsAsFactors = FALSE)
  colnames(x) <- col_names
  x
})

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

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"

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读