【发布时间】:2018-04-15 17:33:17
【问题描述】:
我正在从大型在线数据库 (GBIF) 中抓取数据,这需要三个步骤:(1) 将 GBIF“关键”标识符与物种名称匹配,(2) 向数据库发送查询,获取下载密钥(“res”)作为回报,以及 (3) 下载、导入和过滤与该物种相关的数据。我已经为其中的每一个编写了一个函数(不包括这里的实际代码,因为很遗憾它很长并且需要登录凭据):
get_gbif_key <- function(species) {}
get_gbif_res <- function(gbifkey) {}
get_gbif_dat <- function(gbifres) {}
我有一个数百个物种的列表,我想依次应用这三个函数。我知道它们单独工作,但我不知道如何将它们相互提供(可能使用purrr?)并从前一个函数的嵌套输出中引用正确的输入。
所以,例如:
> testlist <- c('Gadus morhua','Caretta caretta')
> testkey <- map(testlist, get_gbif_key)
> testkey
[[1]]
[1] 8084280
[[2]]
[1] 8894817
这就是我卡住的地方。我想将此列表结构中的键提供给下一个函数,但我不知道如何使用 map 或其他函数正确引用它们。我可以通过手动为下一个函数创建一个新列表来做到这一点:
> testlist2 <- c('8084280','8894817')
> testres <- map(testlist2, get_gbif_res)
> testres
[[1]]
<<gbif download>>
Username: XXXX
E-mail: XXXX@gmail.com
Download key: 0001342-180412121330197
[[2]]
<<gbif download>>
Username: XXXX
E-mail: XXXX@gmail.com
Download key: 0001343-180412121330197
编辑:此输出的结构可能在这里造成问题。当我运行listviewer::jsonedit(testres) 时,它看起来就像一个普通的嵌套列表,其中条目 0 和 1 包含两个下载密钥。但是,当我运行str(testres) 时,我得到以下信息:
> str(testres)
List of 2
$ :Class 'occ_download' atomic [1:1] 0001342-180412121330197
.. ..- attr(*, "user")= chr "XXXX"
.. ..- attr(*, "email")= chr "XXXX@gmail.com"
$ :Class 'occ_download' atomic [1:1] 0001343-180412121330197
.. ..- attr(*, "user")= chr "XXXX"
.. ..- attr(*, "email")= chr "XXXX@gmail.com"
再一次,对于第三个:
> testlist3 <- c('0001342-180412121330197','0001343-180412121330197')
> testdat <- map(testlist3, get_gbif_dat)
它成功地将带有所需数据的列表对象加载到 R 中(它有两个未命名的元素,0 和 1,每个元素都是每个物种的 28 个请求变量的列表)。对于以正确解包前面的列表结构的方式编写此get_gbif_key %>% get_gbif_res %>% get_gbif_dat 工作流的脚本有什么建议吗?
【问题讨论】:
-
没有可复现的例子,很难测试,试试
map(testlist, ~get_gbif_key(.x) %>% get_gbif_res %>% .[3] %>% get_gbif_dat)tesres中的结构不清楚,注释如何提取第三个元素。 -
当我运行那行代码时,我得到一个与中间函数有关的错误,
get_gbif_res。我想我需要在 `%>% get_gbif_res %>%` 中引用前一个函数的输出。我将编辑示例以显示 testres 的结构。 -
我不能像我之前提到的那样测试它
-
如果您想使用地图管道,我建议您将第二个函数的输出更改为只是第三个所需的
occ_download键功能(即删除其他属性,如果不需要的话),那么你应该可以map(testlist, get_gbif_key) %>% map(get_gbif_res) %>% map(get_gbif_dat)
标签: r list function purrr ropensci