【问题标题】:Retrieve pictures from API with R使用 R 从 API 中检索图片
【发布时间】:2021-06-28 14:11:00
【问题描述】:

我从未使用过 API,所以这是我的第一次尝试,我什至不知道我正在尝试做的事情是否可行。

我正在尝试从 SwissBioPics API (https://www.npmjs.com/package/%40swissprot/swissbiopics%2Dvisualizer) 获取细胞图片并将它们放在我的 R 会话中。

res <-  httr::GET('https://www.swissbiopics.org/static/swissbiopics.js',
                     query = list(taxisid = '9606', sls= 'SL0073',gos = '0005641'))
result <- httr::content(res$content)


但我收到此错误:

Error in httr::content(res$content) : is.response(x) is not TRUE

有什么线索吗?

【问题讨论】:

  • 谢天谢地,我想它终于完成了!如果my solution 在您的 RStudio 中工作,请告诉我。

标签: r json api httr


【解决方案1】:

历经千辛万苦,我有你的答案as promised

由于它涉及交互式图像,由 JavaScript 和 HTML 提供,因此该解决方案必须在 RStudio 中作为 .Rmd 文件运行。交互式图像也可以在同名的 .html 文件中访问,当您单击 RStudio 中的 Knit 按钮时,该文件由 knitr 输出。

第一步:项目设置

在 RStudio 中的新目录下创建一个新的 R 项目 my_pics。在这个项目中,创建一个新的 R Notebook(这里是 my_book.Rmd),它应该在上述目录下的 my_pics.Rproj 旁边结束。

第 2 步:支持文件

在同一目录下,创建一个./snippets 子目录。后者应包含以下两个.txt 文件,从swissbiopics-visualizer documentation 复制(并更正):

  • templates.txt:文档中给出的第一个代码块。在这里转载了必要的EOF 和语法更正的 cmets:
<template id="sibSwissBioPicsStyle">
    <style>
        ul > li > a {
            font-style:oblique;
        }
        ul.notpresent li > .subcell_description {
            display:none;
        }
    </style>
</template>
<template id="sibSwissBioPicsSlLiItem">
    <li class="subcellular_location">
         <a class="subcell_name"></a> <!-- the class name is required and textContent will be set on it -->
         <span class="subcell_description"></span> <!-- the class name is required and textContent will be set on it -->
    </li>
</template>

  • custom_element.txt:文档中给出的第三个​​代码块。在此转载必要的EOF
<script type="module" src="https://www.swissbiopics.org/static/swissbiopics.js"></script>
<script defer>
    if (! window.customElements.get("sib-swissbiopics-sl"))
        window.customElements.define("sib-swissbiopics-sl", SwissBioPicsSL);
</script>

请注意,这些.txt 文件可以像.html 文件一样轻松保存。只有文件扩展名需要重构,在templatescustom_element 参数的默认值中,对于下面my_book.Rmd 代码中的make_html() 函数。

第 3 步:在 RStudio 中进行交互

现在我们准备好了!在my_book.Rmd 中写入以下内容:

---
title: "R Notebook"
output: html_document
---


```{r}
library(htmltools)
library(readr)
library(rlang)
```



# Functions #

Here are the functions that do the trick.  The snippets used by `make_html()` are copied from the [documentation](https://www.npmjs.com/package/%40swissprot/swissbiopics-visualizer#usage) for `swissbiopics-visualizer`, and (after fixing the HTML comments) pasted into `.txt` files (`templates.txt` and `custom_element.txt`) under the `./snippets` subdirectory, which lies within the directory containing this `.Rproj`.

```{r}
# Create comma-separated list from vectorized (or listed) items, safely escaped.
csl <- function(items) {
  return(paste("\"", paste(htmltools::htmlEscape(unlist(items)), collapse = ",", sep = ""), "\"", sep = ""))
}



# Create the HTML for the interactive imagery given by the parameters. Assembly
# process is as described the documentation for 'swissbiopics-visualizer':
#   https://www.npmjs.com/package/%40swissprot/swissbiopics-visualizer#usage
make_html <- function(# The NCBI taxonomy ID.
                      tax_id,
                      
                      # The IDs of the cellular elements to highlight.
                      sl_ids,
                      
                      # The filepath to (or raw HTML text of) the templates
                      # snippet.
                      templates = "./snippets/templates.txt",
                      
                      # The filepath to (or raw HTML text of) the custom element
                      # snippet.
                      custom_element = "./snippets/custom_element.txt",
                      
                      # Further arguments to 'readr::read_file()', which might
                      # be useful to process snippet encodings across platforms.
                      ...) {
  # Escape any strings supplied.
  tax_id <- csl(tax_id[1])
  sl_ids <- csl(sl_ids)
  
  
  # Compile all the HTML snippets into a list:
  elements <- list()
  
  
  # Include the templates (as read)...
  elements$templates <- readr::read_file(file = templates, ...)
  
  
  # ...then include the line (created here) to target the right picture...
  elements$identifier <- "<sib-swissbiopics-sl taxid=%s sls=%s></sib-swissbiopics-sl>"
  elements$identifier <- sprintf(fmt = elements$identifier, tax_id, sl_ids)
  
  
  # ...and finally include the definition (as read) for the custom element.
  elements$custom_element <- readr::read_file(file = custom_element, ...)
  
  
  # Append these snippets together, into the full HTML code.
  return(paste(unlist(elements), collapse = "\n"))
}



# Display the interactive imagery given by the parameters, visible in both
# RStudio (crowded) and the R Markdown file (well laid out).
visualize <- function(# The NCBI taxonomy ID.
                      taxid = "9606",
                      
                      # A list (or vector) of the UniProtKB subcellular location
                      # (SL) IDs for the cellular elements to highlight.
                      sls = list("SL0073"),
                      
                      # Further arguments to 'make_html()'.
                      ...
                      ) {
  # Embed the HTML text where this function is called.
  return(htmltools::HTML(make_html(tax_id = taxid, sl_ids = sls, ...)))
}
```



# Results #

Here we `visualize()` the **interactive** image, also accessible on [SwissBioPics](https://www.swissbiopics.org):

```{r}
visualize(sls = list("SL0073", "SL0138"))
```

注意

观察(在这种情况下)我们如何“懒惰地”使用taxid 的默认值 ("9606"),而无需指定它。还要观察我们如何同时突出显示不是一个而是多个单独的组件,即Contractile vacuole ("SL0073") 和Cell cortex ("SL0138")。


现在在调用 visualize() 的最后一个块下方

```{r}
visualize(sls = list("SL0073", "SL0138"))
```

您将看到如下所示的交互式输出:

遗憾的是,它在 RStudio 中显得非常拥挤,可能需要一个 HTML 向导来更改支持的 .txt(或 .html)文件,以在此 IDE 中实现格式正确的 HTML。

第 4 步:嵌入报告

与任何.Rmd 文件一样,RStudio 为您提供了将 Markdown 结果编织.html 文件的选项,该文件可以轻松访问且格式精美作为报告

在 RStudio 中打开 my_book.Rmd 后,单击 Knit 按钮,my_book.html 应出现在同一目录中。您可以在网络浏览器(我使用 Chrome)中打开此 .html 文件,以查看它的全部荣耀!

总结

使用这两个交互式图像中的任何一个,您都可以悬停以突出显示图表的各个组件和层。此外,单击任何定义将通过超链接转到其在UnitProt 上的个人资料。

许多剩余的限制是由于swissbiopics-visualizer API 本身造成的。例如,它的mappingGO IDsSL IDs 似乎有故障,通过this dataset。因此,您应该向visualize()提供SL代码。

也就是说,如果您可以处理该 HTML 并根据自己的意愿调整其布局,那么天空就是极限!

享受吧!


奖金

这是一个相同交互式输出的演示,嵌入在 Stack Overflow 中!不幸的是,它在这种环境下不稳定且非常笨拙,所以我把它作为一个“脚注”:

<template id="sibSwissBioPicsStyle">
    <style>
        ul > li > a {
            font-style:oblique;
        }
        ul.notpresent li > .subcell_description {
            display:none;
        }
    </style>
</template>
<template id="sibSwissBioPicsSlLiItem">
    <li class="subcellular_location">
         <a class="subcell_name"></a> <!-- the class name is required and textContent will be set on it -->
         <span class="subcell_description"></span> <!-- the class name is required and textContent will be set on it -->
    </li>
</template>


<sib-swissbiopics-sl taxid="9606" sls="SL0073,SL0138" ></sib-swissbiopics-sl>


<script type="module" src="https://www.swissbiopics.org/static/swissbiopics.js"></script>
<script defer>
    if (! window.customElements.get("sib-swissbiopics-sl"))
        window.customElements.define("sib-swissbiopics-sl", SwissBioPicsSL);
</script>

【讨论】:

  • 它工作得非常好,也适用于不同的 taxId 和不同的子单元类型。在接受之前只是一个后续问题(最后我保证)。如果我想将单元格图片保存为静态图像,我是否必须弄乱 JavaScript 代码?还是有更直接的方法?
  • @CodingBiology 嗯……让我看看。该解决方案的优势在于其模块化。 JS 脚本由 HTML 自动调用,在最后一个 sn-p 中;而且由于该脚本从未明确写出,而是从该站点获取(src="https://www.swissbiopics.org/static/swissbiopics.js"),因此我们永远不会真正摆弄文字 JS 文本本身。它使事物保持清洁和划分,尽管以抽象的(通常较小的)成本为代价。
  • 认为我有一个解决方案,虽然它可能会有点混乱。
  • webshot2 延迟一秒对我来说效果很好:)
  • 顺便说一句 @Greg,我正在用它创建一个 R 包,所以如果你想合作的话,我们非常欢迎:)
【解决方案2】:

您必须在res 上调用content 函数,而不是res$content。然后你得到需要转换的原始内容,例如通过

base::rawToChar(content(res))

这会产生一个包含一些 JS 代码的字符串

base::rawToChar(content(res))
[1] "var SwissBioPics;SwissBioPics=(()=>....

【讨论】:

  • 谢谢,@Jonas,它可以工作,但我不知道现在如何从那个 JS 代码继续到我想要获取的图片?
  • @CodingBiology 当您说“我正在尝试获取细胞图片...并在我的 R 会话中包含它们”时,您在想象什么??您希望 图像本身 在 RStudio 中呈现吗?还是您希望 RStudio 中的数据可以作为图像文件保存到您的计算机?
  • 我确实想要图像本身。例如,Uniprot 使用 swiss biopics 的 API 来渲染这些图像:uniprot.org/uniprot/P04637 但是第二个选项可能是一种解决方法,我也许可以让它工作
  • @CodingBiology 您是否希望这些图像在 R Markdown 报告中呈现?如果是这样,您可以将它们保存到您的.Rproj 中的/images 目录中,并让knitr 在报告中呈现它们。
  • @CodingBiology 我想我有你的解决方案,但我必须把 2 和 2 放在一起......
【解决方案3】:

我只是快速浏览了网站,但是下载文件呢?它还通过 API。

qurl = "https://www.swissbiopics.org/api/image/Chlamydomona_cells.svg"
fl = file.path(tempdir(), basename(qurl))

download.file(qurl, fl)

一旦在磁盘上,您可以在 R 中加载图像,例如通过magick-package:

require(magick)

img = image_read_svg(fl)
print(img)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 2012-04-24
    • 1970-01-01
    相关资源
    最近更新 更多