首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R:从Pubchem解析JSON/XML导出的复合属性

R:从Pubchem解析JSON/XML导出的复合属性
EN

Stack Overflow用户
提问于 2015-09-17 15:33:33
回答 1查看 818关注 0票数 1

我想使用JSON (或XML)导出工具解析给定化合物的所有化学性质,如在R中的Pubchem中给出的那样。

例子:α-紫罗兰酮,pubchem化合物ID 5282108

https://pubchem.ncbi.nlm.nih.gov/compound/5282108

代码语言:javascript
复制
library("rjson")
data <- rjson::fromJSON(file="https://pubchem.ncbi.nlm.nih.gov/rest/pug_view/data/compound/5282108/JSON/?response_type=display")

代码语言:javascript
复制
library("RJSONIO")
data <- RJSONIO::fromJSON("https://pubchem.ncbi.nlm.nih.gov/rest/pug_view/data/compound/5282108/JSON/?response_type=display")

将给我一棵嵌套列表树,但是我如何从这个相当复杂的嵌套列表到一个很好的dataframe或dataframes列表呢?

在这种情况下,我想要的是

3.1计算描述符

3.2其他标识符

3.3同义词

4.1计算性质

在一个dataframe的一行中,在一个单独命名列中的每个元素中,每个元素都有多个项(例如多个同义词),每个元素都粘贴在一起作为分隔符。在这种情况下,就像

代码语言:javascript
复制
pubchemid      IUPAC_Name    InChI       InChI_Key     Canonical SMILES      Isomeric SMILES     CAS     EC Number     Wikipedia      MeSH Synonyms     Depositor-Supplied Synonyms   Molecular_Weight    Molecular_Formula    XLogP3   Hydrogen_Bond_Donor_Count ... 
5282108        (E)-4-(2,6,6-trimethylcyclohex-2-en-1-yl)but-3-en-2-one       InChI=1S/C13H20O/c1-10-6-5-9-13(3,4)12(10)8-7-11(2)14/h6-8,12H,5,9H2,1-4H3/b8-7+ ....

包含多个项的字段,例如保存器提供的同义词,可以与“AC.26”粘贴在一起,例如,值可以是ALPHA-紫罗兰-Iraldeine.

第二,我还想导入4.2.2节Kovats保留指数作为数据

代码语言:javascript
复制
pubchemid      column_class            kovats_ri
5282108        Standard non-polar      1413
5282108        Standard non-polar      1417
...
5282108        Semi-standard non-polar 1427
...

(第4.3.1节GC-MS也很好,但是由于它只显示了3个顶部的峰值,这现在有点没用,所以我跳过它)

有人知道如何以优雅的方式实现这一点吗?

注意,对于任何给定的查询,并不一定存在所有这些字段。

二维结构和一些性质也可以从

type=display

的三维结构

type=display

也可以将数据导出为XML,使用

type=display

如果这更容易的话

注意: available rpubchem也尝试过,但似乎只导入了少量的可用信息:

代码语言:javascript
复制
library("rpubchem")
get.cid(5282108)
CID  IUPACName CanonicalSmile MolecularFormula MolecularWeight TotalFormalCharge XLogP HydrogenBondDonorCount HydrogenBondAcceptorCount HeavyAtomCount    TPSA
2 5282108 (E)-4-(2,6,6-trimethylcyclohex-2-en-1-yl)but-3-en-2-one        C13H20O       192.297300               0                 3     0                      1                        14             17 5282108
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-21 19:55:22

我的建议适用于XML文件,因为(感谢XPath),我发现它们更便于遍历和选择节点。

请注意,这既不快(测试时花费了几秒时间),也不是最优的(我对每个文件解析了两次--一次用于名称等,一次用于Kovats保留索引)。但是我想您会想要一次解析一些文件集,然后继续您真正的业务,而过早的优化是所有问题的根源。

我已将主要任务分成不同的职能。如果您想获取特定pubchem记录的数据,则可以使用它们。但是,如果您想一次从几个pubchem记录中获取数据,您可以定义指向数据的指针向量,并在底部使用示例将结果合并在一起。在我的例子中,向量包含指向本地磁盘上文件的路径。URL也是受支持的,尽管我会劝阻它们(请记住,每个站点将被请求两次,如果有更多的记录,您可能希望以某种方式处理错误的网络)。

您所链接的化合物在"EC编号“上有多个条目。他们确实有不同的ReferenceNumber,但没有在Name。我不知道为什么会这样,我应该如何处理它(您的示例输出只包含一个EC号条目),所以我把它留给R. R添加后缀到复制的值中,并创建了EC.Number.1EC.Number.2等。这些后缀在文件中与ReferenceNumber不匹配,而且主数据帧中的同一列可能会针对不同的组合引用不同的ReferenceNumber

看起来pubchem为标记<type>Value[List]使用了以下格式。在少数地方,我有硬编码的StringValue,但可能有些化合物在相同的字段中有不同的类型。我通常没有考虑过清单,除了被要求的地方。因此,在这段代码中抛出更多数据时,可能需要进一步的修改。

如果您有任何问题,请张贴在评论。我不确定是否该解释这段代码。

代码语言:javascript
复制
library("xml2")
library("data.table")

compound.attributes <- function(file=NULL) {
  compound <- read_xml(file)
  ns <- xml_ns(compound)
  information <- xml_find_all(compound, paste0(
    "//d1:TOCHeading[text()='Computed Descriptors'",
    " or text()='Other Identifiers'",
    " or text()='Synonyms'",
    " or text()='Computed Properties']",
    "/following-sibling::d1:Section/d1:Information"
  ), ns)

  properties <- sapply(information, function(x) {
    name <- xml_text(xml_find_one(x, "./d1:Name", ns))
    value <- ifelse(length(xml_find_all(x, "./d1:StringValueList", ns)) > 0,
                    paste(sapply(
                      xml_find_all(x, "./d1:StringValueList", ns),
                      xml_text, trim=TRUE), sep="", collapse="|"),
                    xml_text(
                      xml_find_one(x, "./*[contains(name(),'Value')]", ns),
                      trim=TRUE)
    )
    names(value) <- name
    return(value)
  })
  rm(compound, information)
  properties <- as.list(properties)
  properties$pubchemid <- sub(".*/([0-9]+)/?.*", "\\1", file)
  return(data.frame(properties))
}

compound.retention.index <- function(file=NULL) {
  pubchemid <- sub(".*/([0-9]+)/?.*", "\\1", file)
  compound <- read_xml(file)
  ns <- xml_ns(compound)
  information <- xml_find_all(compound, paste0(
    "//d1:TOCHeading[text()='Kovats Retention Index']",
    "/following-sibling::d1:Information"
  ), ns)
  indexes <- lapply(information, function(x) {
    name <- xml_text(xml_find_one(x, "./d1:Name", ns))
    values <- as.numeric(sapply(
      xml_find_all(x, "./*[contains(name(), 'NumValue')]", ns), 
      xml_text))

    data.frame(pubchemid=pubchemid,
               column_class=name,
               kovats_ri=values)
  })

  return( do.call("rbind", indexes) )
}

compounds <- c("./5282108.xml", "./5282148.xml", "./91754124.xml")

cd <- rbindlist(
  lapply(compounds, compound.attributes),
  fill=TRUE
)

rti <- do.call("rbind",
               lapply(compounds, compound.retention.index))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32634430

复制
相关文章

相似问题

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