Cập nhật 2 @G. Grothendieck đăng hai cách tiếp cận. Thứ hai là thay đổi môi trường chức năng bên trong một hàm. Điều này giải quyết vấn đề của tôi quá nhiều bản sao mã hóa. Tôi không chắc chắn nếu đây là một phương pháp tốt để vượt qua kiểm tra CRAN khi làm cho các kịch bản của tôi thành một gói. Tôi sẽ cập nhật lại khi tôi có một số kết luận.Trong R, làm thế nào để biến các biến bên trong một hàm có sẵn cho hàm mức thấp hơn bên trong hàm này? (Với, đính kèm, môi trường)
Cập nhật
Tôi cố gắng để vượt qua rất nhiều biến tranh luận đầu vào f2
và không muốn đánh chỉ mục tất cả các biến bên trong hàm như env$c, env$d, env$calls
, đó là lý do tại sao tôi đã cố gắng để sử dụng with
trong f5
và f6
(sửa đổi f2
). Tuy nhiên, assign
không làm việc với with
bên trong {}
, di chuyển assign
ngoài with
sẽ làm công việc nhưng trong trường hợp thật của tôi Tôi có một vài assign
s bên trong with
biểu thức mà tôi không biết làm thế nào để di chuyển chúng ra khỏi with
chức năng một cách dễ dàng .
Dưới đây là một ví dụ:
## 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()
Chức năng f2
là bên trong f1
, khi f2
được gọi, nó sẽ tìm kiếm các biến calls,c,d
trong môi trường environment(f1)
. Đây là những gì tôi muốn.
Tuy nhiên, khi tôi muốn sử dụng f2
cũng có trong các chức năng khác, tôi sẽ xác định chức năng này trong môi trường toàn cầu thay vào đó, gọi nó là f4
.
f4 <- function(P){
assign("calls", calls+1, inherits=TRUE)
print(calls)
return(P+c+d)
}
này sẽ không làm việc, bởi vì nó sẽ tìm kiếm calls,c,d
trong môi trường toàn cầu thay vì bên trong một hàm mà hàm được gọi. Ví 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()
Cách an toàn nên được xác định calls,c,d
trong các đối số đầu vào của f4
và sau đó vượt qua các thông số này vào f4
. Tuy nhiên, trong trường hợp của tôi, có quá nhiều biến được chuyển vào hàm này f4
và tốt hơn là tôi có thể chuyển nó thành môi trường và yêu cầu f4
không nhìn vào môi trường Toàn cầu (environment(f4)
), chỉ nhìn vào bên trong environment
khi gọi f3
.
Cách tôi giải quyết ngay bây giờ là sử dụng môi trường làm danh sách và sử dụng chức năng 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()
Tuy nhiên, bây giờ assign("calls", calls+1, inherits=TRUE)
không hoạt động như nó phải được kể từ assign
không sửa đổi đối tượng gốc. Biến số calls
được kết nối với chức năng tối ưu hóa trong đó hàm mục tiêu là f5
. Đó là lý do tôi sử dụng assign
thay vì chuyển số calls
làm đối số nhập. Sử dụng attach
cũng không rõ ràng với tôi.Đây là cách của tôi để sửa chữa vấn đề 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()
Tôi không chắc chắn cách này nên được thực hiện trong R. Am tôi về đúng hướng, đặc biệt là khi đi qua cran kiểm tra? Bất cứ ai cũng có một số gợi ý về điều này?
Điều này cho kết quả tôi muốn nhưng tôi không viết rõ ràng yêu cầu của tôi. Trong thực tế, tôi muốn tránh lập chỉ mục tất cả các biến đi vào 'f2', tức là, không viết' env $ ', đó là lý do tại sao tôi cố gắng sử dụng' with'. Tôi muốn có thể thay đổi 'bên ngoài' bên trong 'f2' nhưng không thay đổi các biến khác trong môi trường hiện tại. Tôi sẽ cập nhật câu hỏi. – Zhenglei
Tôi đã thêm phương pháp thứ hai. –
Nó trông giống như những gì tôi cần. Tôi sẽ kiểm tra nó với trường hợp thực sự của tôi và cập nhật sau. Cảm ơn bạn rất nhiều vì sự giúp đỡ! – Zhenglei