我从大型在线数据库(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
工作流脚本的任何建议吗?
答案 0 :(得分:0)
根据目前提供的证据,您应该尝试以下内容。基本上,结果表明您应该能够使用嵌套map
- ping:
yourData <- map( unlist( # to make same class as your single func version
map(
map(testlist,
get_gbif_key), # returns gbifkeys
get_gbif_res)), # returns gbif_res's
get_gbif_dat) # returns data items
你展示结构的最后一项只是一个带有一些额外属性的原子字符向量列表,你的函数似乎没有遇到困难,所以映射应该成功。