Обновить 2 @G. Гротендик опубликовал два подхода. Второй - изменение функциональной среды внутри функции. Это решает мою проблему слишком большого количества копий. Я не уверен, что это хороший способ пройти проверку CRAN, когда мои скрипты попадают в пакет. Я еще раз обновлюсь, когда у меня появятся некоторые выводы.
Обновить
Я пытаюсь передать много переменных входных аргументов в f2
и не хочу индексировать каждую переменную внутри функции как env$c, env$d, env$calls
, поэтому я пытался использовать with
f5
и f6
( измененный f2
). Однако assign
не работает with
внутри {}
, перемещение assign
снаружи with
будет делать эту работу, но в моем реальном случае у меня есть несколько assign
внутри 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
переменных calls,c,d
в среде environment(f1)
. Это то, чего я хотел.
Однако, когда я хочу использовать f2
также в других функциях, я буду определять эту функцию в глобальной среде, назовите ее 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)
не работают так, как должно быть, поскольку 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? У кого-нибудь есть намеки на это?