问题
关于这个玩具问题,我想了解为什么当一个函数调用另一个函数时,列表没有更新。如果我在第二个函数之外运行代码,则会更新相同的列表。
可复制示例:
以下功能更新以前为空的列表SControlModelStates()
:
library(pracma)
func_1 <- function(VTimeStamp,
iSample,
SParameters){
# is this the first time step?
if (pracma::isempty(SControlModelStates)){
stopifnot(iSample == 1)
# set default values for any unspecified model parameters
if (!('my_param' %in% names(SParameters))){
SParameters[['my_param']] <- 5
}
SControlModelStates[['my_val']] <- rep(0, length(VTimeStamp))
} else {
# this is not the first time step
SControlModelStates[['my_val']][iSample] <- SControlModelStates[['my_val']][iSample-1] + SParameters[['my_param']]
}
res <- list('SParameters' = SParameters,
'SControlModelStates' = SControlModelStates)
res
}
运行函数:
当我运行上述功能时,它成功地更新了SControlModelStates()
:
SControlModelStates <- list()
Parameters <- list()
VTimeStamp <- 1:5
for (i in 1:length(VTimeStamp)){
foo <- func_1 (VTimeStamp,
i,
Parameters)
Parameters <- foo[["SParameters"]]
SControlModelStates <- foo[["SControlModelStates"]]
}
> SControlModelStates
$my_val
[1] 0 5 10 15 20
在另一个函数中调用上述函数会产生错误:
重新启动R
后,我执行了以下操作:
## Function definition
func_2 <- function(VTimeStamp){
SControlModelStates <- list()
Parameters <- list()
VTimeStamp <- VTimeStamp
for (i in 1:length(VTimeStamp)){
foo <- func_1 (VTimeStamp,
i,
Parameters)
Parameters <- foo[["SParameters"]]
SControlModelStates <- foo[["SControlModelStates"]]
}
return(SControlModelStates[["my_val"]])
}
## Running the function:
> func_2(1:5)
Error in pracma::isempty(SControlModelStates) :
object 'SControlModelStates' not found
这表示CCD_ 4在CCD_。i==2
。如何修复func_2
以解决此问题?
您的问题是变量范围的问题。
for循环按原样运行之所以有效,是因为您将SControlModelStates
定义为全局变量,func_1
可以访问它
当运行func_2
时,func_1
不能访问调用环境(func_1
和全局),只能访问它在(全局)中定义的环境,但全局环境在干净的R运行时中没有变量SControlModelStates
。
如果要引用现有的SControlModelStates
,则需要将其作为参数传递给func_1
(首选)或使用全局变量。