map_df未传递iso2参数报错:IMF API数据提取函数故障排查
问题:imf.data包调用IMF API时出现
iso2未找到的错误 我需要用imf.data包从IMF API加载数据,同时提取多个长度可能不同的指标。编写了getFAfromIFS函数,通过map_df遍历指标列表调用get_series接口,但运行时报错提示iso2未找到。
原代码
library(tidyverse) library(data.table) library(imf.data) # 示例指标向量 index <- c( # FA - Direct Investment "BFDA_BP6_USD", "BFDAD_BP6_USD", "BFDAE_BP6_USD", # FA - Portfolio Investment "BFPA_BP6_USD", "BFPAD_BP6_USD", "BFPAE_BP6_USD" ) getFAfromIFS <- function(iso2 = "US") { dta_IFS <- imf.data::load_datasets("IFS") index <- c( # FA - Direct Investment "BFDA_BP6_USD", "BFDAD_BP6_USD", "BFDAE_BP6_USD", # FA - Portfolio Investment "BFPA_BP6_USD", "BFPAD_BP6_USD", "BFPAE_BP6_USD" ) each_dta.byeachISO2 <- map_df(index, function(xxx) { print(paste0("...loading data from iso2=", iso2, " & index=", xxx)) each_account <- dta_IFS$get_series(freq = "Q", ref_area = iso2, indicator = xxx) print("... check? ") each_account %>% setDT() %>% setnames(c("time", "value", "Note")) %>% select(-Note) %>% .[, `:=` (ISO2 = iso2, index = xxx)] }) %>% dcast( time + ISO2 ~ index, value.var = "value") } data1 <- getFAfromIFS(iso2 = "US")
报错信息
Error in `map()`: ℹ In index: 1. Caused by error: ! object 'iso2' not found Run `rlang::last_trace()` to see where the error occurred.
问题原因与解决方案
原因
报错核心是map_df中的匿名函数无法正确捕获外层函数getFAfromIFS的iso2参数。imf.data的get_series方法内部执行时,调用环境脱离了当前函数作用域,导致无法找到iso2变量。
修正方案
将iso2作为额外参数显式传递给map_df的匿名函数,确保变量能被正确捕获。修改后的代码如下:
library(tidyverse) library(data.table) library(imf.data) getFAfromIFS <- function(iso2 = "US") { dta_IFS <- imf.data::load_datasets("IFS") index <- c( # FA - Direct Investment "BFDA_BP6_USD", "BFDAD_BP6_USD", "BFDAE_BP6_USD", # FA - Portfolio Investment "BFPA_BP6_USD", "BFPAD_BP6_USD", "BFPAE_BP6_USD" ) # 关键修改:显式传递iso2参数给匿名函数 each_dta.byeachISO2 <- map_df(index, function(xxx, iso2_val) { print(paste0("...loading data from iso2=", iso2_val, " & index=", xxx)) each_account <- dta_IFS$get_series(freq = "Q", ref_area = iso2_val, indicator = xxx) print("... check? ") each_account %>% setDT() %>% setnames(c("time", "value", "Note")) %>% select(-Note) %>% .[, `:=` (ISO2 = iso2_val, index = xxx)] }, iso2_val = iso2) %>% # 将外层iso2传递到匿名函数 dcast( time + ISO2 ~ index, value.var = "value") } data1 <- getFAfromIFS(iso2 = "US")
可选简化方案
如果偏好公式风格匿名函数,可通过.env指定环境直接调用外层变量:
each_dta.byeachISO2 <- map_df(index, ~{ print(paste0("...loading data from iso2=", .env$iso2, " & index=", .x)) each_account <- dta_IFS$get_series(freq = "Q", ref_area = .env$iso2, indicator = .x) # 后续处理逻辑不变 }) %>% dcast( time + ISO2 ~ index, value.var = "value")
内容的提问来源于stack exchange,提问作者Caleb
相关产品推荐
相关产品推荐

