更新 2 @G。Grothendieck 发布了两种方法。第二个是改变函数内部的函数环境。这解决了我编码重复过多的问题。我不确定这是否是在将我的脚本放入包时通过 CRAN 检查的好方法。当我有一些结论时,我会再次更新。
更新
我试图将很多输入参数变量传递给f2
并且不想将函数内的每个变量索引为env$c, env$d, env$calls
,这就是我尝试使用with
inf5
和f6
(修改后的f2
)的原因。但是,assign
不能在with
内部使用{}
,移到assign
外部with
可以完成这项工作,但在我的实际情况下,我assign
在表达式中有一些 s with
,我不知道如何with
轻松地将它们移出函数。
这是一个例子:
## In the <environment: R_GlobalEnv>
a <- 1
b <- 2
f1 <- function(){
c <- 3
d <- 4
f2 <- function(P){
assign("calls", calls+1, inherits=TRUE)
print(calls)
return(P+c+d)
}
calls <- 0
v <- vector()
for(i in 1:10){
v[i] <- f2(P=0)
c <- c+1
d <- d+1
}
return(v)
}
f1()
函数f2
在里面f1
,当被调用时,它会在环境中f2
寻找变量。这就是我想要的。calls,c,d
environment(f1)
但是,当我还想f2
在其他函数中使用时,我将在 Global 环境中定义这个函数,调用它f4
。
f4 <- function(P){
assign("calls", calls+1, inherits=TRUE)
print(calls)
return(P+c+d)
}
这不起作用,因为它将calls,c,d
在全局环境中而不是在调用函数的函数内部查找。例如:
f3 <- function(){
c <- 3
d <- 4
calls <- 0
v <- vector()
for(i in 1:10){
v[i] <- f4(P=0) ## or replace here with f5(P=0)
c <- c+1
d <- d+1
}
return(v)
}
f3()
安全的方式应该calls,c,d
在 的输入参数中定义f4
,然后将这些参数传递给f4
. 但是,在我的例子中,有太多的变量要传递给这个函数f4
,我可以将它作为环境传递并告诉f4
不要查看全局环境(environment(f4)
),只查看调用environment
时f3
的内部。
我现在解决的方法是把环境当成列表,使用with
函数。
f5 <- function(P,liste){
with(liste,{
assign("calls", calls+1, inherits=TRUE)
print(calls)
return(P+c+d)
}
)
}
f3 <- function(){
c <- 3
d <- 4
calls <- 0
v <- vector()
for(i in 1:10){
v[i] <- f5(P=0,as.list(environment())) ## or replace here with f5(P=0)
c <- c+1
d <- d+1
}
return(v)
}
f3()
但是,由于不会修改原始对象,assign("calls", calls+1, inherits=TRUE)
因此 now 无法正常工作。assign
该变量calls
与目标函数为 的优化函数相关联f5
。这就是我使用而不是作为输入参数assign
传递的原因。我也不清楚calls
使用。attach
这是我纠正assign
问题的方法:
f7 <- function(P,calls,liste){
##calls <<- calls+1
##browser()
assign("calls", calls+1, inherits=TRUE,envir = sys.frame(-1))
print(calls)
with(liste,{
print(paste('with the listed envrionment, calls=',calls))
return(P+c+d)
}
)
}
########
##################
f8 <- function(){
c <- 3
d <- 4
calls <- 0
v <- vector()
for(i in 1:10){
##browser()
##v[i] <- f4(P=0) ## or replace here with f5(P=0)
v[i] <- f7(P=0,calls,liste=as.list(environment()))
c <- c+1
d <- d+1
}
f7(P=0,calls,liste=as.list(environment()))
print(paste('final call number',calls))
return(v)
}
f8()
我不知道这应该如何在 R 中完成。我的方向是否正确,尤其是在通过 CRAN 检查时?有人对此有一些提示吗?