You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 18:10:42