将函数与 purrr 链接起来并引用嵌套变量
linking functions with purrr and referencing nested variables
我正在从大型在线数据库 (GBIF) 中抓取数据,这需要三个步骤:(1) 将 GBIF "key" 标识符与物种名称相匹配,(2) 向数据库发送查询,在 return 中获取下载密钥 ("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
-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
您显示的最后一项结构只是一个具有一些额外属性的原子字符向量列表,您的函数似乎可以毫无困难地处理它,因此映射应该会成功。
我正在从大型在线数据库 (GBIF) 中抓取数据,这需要三个步骤:(1) 将 GBIF "key" 标识符与物种名称相匹配,(2) 向数据库发送查询,在 return 中获取下载密钥 ("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
-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
您显示的最后一项结构只是一个具有一些额外属性的原子字符向量列表,您的函数似乎可以毫无困难地处理它,因此映射应该会成功。