Обновить 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? У кого-нибудь есть намеки на это?