使用map_dfc调用accumulate时wAmt参数缺失问题求助
蒙特卡洛模拟提款通胀调整代码调试
我正在修改《Reproduceable Finance with R》中的蒙特卡洛代码,以处理提款及提款的通胀调整。修改模拟累加函数后调用时抛出参数缺失错误,具体信息及代码如下:
错误信息
Error in
map():
ℹ In index: 1.
Caused by error inmutate():
! Problem while computinggrowth = accumulate(returns, function(x, y, wAmt) x * y - wAmt).
Caused by error infn():
! argument "wAmt" is missing, with no default
Backtrace:
- purrr::map_dfc(...)
- purrr::accumulate(returns, function(x, y, wAmt) x * y - wAmt)
- purrr:::reduce_impl(...)
- fn(out, elt, ...)
Error in map(.x, .f, ...) :
现有代码
模拟累加函数
simulation_accum_withdrawls <- function(init_value, N, mean, stdev, wAmt) { tibble(c(init_value, 1 + rnorm(N, mean, stdev),wAmt)) %>% `colnames<-`("returns") %>% mutate(growth = accumulate(returns, function(x, y, wAmt) x * y - wAmt)) %>% select(growth) }
函数调用代码
monte_carlo_sim <- map_dfc(starts, simulation_accum_withdrawls, N = sim_duration_months, mean = geo_mean_port_return, stdev = geo_stddev_port_return, wAmt = inflated_withdrawls)
数据结构
inflated_withdrawls为非空数据框,结构如下:
str(inflated_withdrawls) 'data.frame': 38 obs. of 1 variable: $ wAmt: num 1805391 0 0 0 0 ...
错误原因及修正方案
核心错误点
- 向量拼接错误:原函数将
init_value、收益率序列、wAmt直接拼接成tibble的一列,导致序列长度混乱(应为1 + N个元素,实际变成1 + N + 38),完全不符合周期对应关系。 accumulate参数传递错误:accumulate的回调函数默认仅接收前一期结果x和当前元素y,额外的wAmt参数无法自动传入,导致参数缺失报错。
修正后的函数
改用accumulate2同时处理收益率和提款额两个序列,确保每个周期对应正确的提款金额:
simulation_accum_withdrawls <- function(init_value, N, mean, stdev, wAmt) { # 提取wAmt向量并验证长度:初始值+N个周期,共N+1个提款额 w_vec <- pull(wAmt, wAmt) stopifnot(length(w_vec) == N + 1) # 生成N个收益率(1+收益率),加上初始值得到完整序列 returns_seq <- c(init_value, 1 + rnorm(N, mean, stdev)) # 用accumulate2同时迭代收益率和提款额 tibble( returns = returns_seq, wAmt = w_vec ) %>% mutate( growth = accumulate2( .x = returns[-1], # 从第2个元素开始的收益率 .y = w_vec[-1], # 从第2个元素开始的提款额 .init = returns[1],# 初始值作为累加起点 .f = function(current_val, next_return, next_withdraw) { current_val * next_return - next_withdraw } ) ) %>% select(growth) }
调试步骤
- 单独测试函数:先传入单个
init_value调用simulation_accum_withdrawls,确认能正常生成结果后,再用map_dfc批量处理。 - 验证长度匹配:确保
sim_duration_months + 1等于inflated_withdrawls的行数(当前为38行,所以sim_duration_months应为37)。 - 检查提款逻辑:根据需求确认提款是在周期收益计算后扣除还是初始时扣除,调整
w_vec的索引即可。
内容的提问来源于stack exchange,提问作者qplan
相关产品推荐
相关产品推荐

