使用future_map时函数无法识别radiusCluster参数的问题解决
问题描述
代码目标是基于Poisson Matern聚类分布生成1000个景观,通过随机分配点实现动态景观。运行时出现以下问题:
- 未在
future_map中指定radiusCluster时,radiusCluster被错误赋值,导致runif生成NA,景观无法正常生成 - 尝试在
future_map中加入radiusCluster=50时,被判定为未使用参数,代码无法运行
错误提示:
In runif(numbparents, 0 + radiusCluster, dim - radiusCluster) : NAs produced
问题原因分析
- 参数传递逻辑错误:
future_map(.x, .f, ...)会将.x(即episet的每个元素:1到1000)作为第一个参数传递给.f(generate_landscape)。而generate_landscape的第一个参数是radiusCluster,因此radiusCluster被依次赋值为1、2、...、1000,完全覆盖了函数定义中的默认值50。当radiusCluster大于等于dim/2(比如500)时,runif的上下限0+radiusCluster和dim-radiusCluster会相等甚至反转,直接生成NA值。 - 重复参数冲突:当手动在
future_map中添加radiusCluster=50时,future_map同时传递了episet的元素和手动指定的50给同一个参数,导致参数重复,触发“未使用参数”的报错。
修正方案
有两种简单的修正方式:
方式一:用匿名函数包裹调用(推荐)
不需要修改原函数,仅调整future_map的调用方式,让episet的元素不被传递给generate_landscape的参数(因为episet只是用来控制循环次数,不需要实际传入函数):
# Generate the landscapes in parallel landscapes <- future_map(episet, ~generate_landscape( radiusCluster=50, lambdaParent=.05, lambdaDaughter=25, randmod=0, hosts=1000, dim=1000))
这里的~是R中匿名函数的简写,等价于function(x) generate_landscape(...),其中x接收episet的元素但不会被使用,这样所有参数都由手动指定,radiusCluster会正确取到50的值。
方式二:调整函数参数顺序
将generate_landscape的第一个参数改为一个占位参数(比如sim_id),用来接收episet的元素,后续参数保持不变:
# 修改函数定义 generate_landscape<-function(sim_id, # 新增占位参数,接收episet的元素 radiusCluster=50, lambdaParent, lambdaDaughter, randmod, hosts, dim){ # 函数内部逻辑不变,不需要用到sim_id numbparents<-rpois(1,lambdaParent*dim) # ... 其余代码保持原样 } # 调用时无需指定sim_id,future_map会自动传递episet的元素 landscapes <- future_map(episet, generate_landscape, radiusCluster=50, lambdaParent=.05, lambdaDaughter=25, randmod=0, hosts=1000, dim=1000)
这样episet的元素会被传递给sim_id参数,不会干扰radiusCluster的赋值,同时手动指定的radiusCluster=50会正常生效。
验证修正效果
运行修正后的代码,radiusCluster会被正确识别为50,runif的上下限为0+50=50和1000-50=950,不会生成NA,景观可以正常生成。最后用ggplot查看第一个景观的代码也能正常运行。
内容的提问来源于stack exchange,提问作者OpenSauce
相关产品推荐
相关产品推荐

