Phân tích và đánh giá các hàm trong R


8

Cho hàm sau

f <- function(x) {
    g <- function(y) {
            y + z
    }
    z <- 4
    x + g(x)
 }

Nếu một người chạy mã sau trong R tại sao câu trả lời là 10? Tôi hơi bối rối về cách y chơi trong câu hỏi này.

z <- 10
f(3)

2
Nó nhận được 'z' từ bên trong hàm env
akrun

5
Không phải là chức năng chỉ làm 4 + 2*xcuối cùng sao? Trong đó 4 = z
markus

1
@markus Có, nhưng câu hỏi là, tại sao z = 4? Có thể hợp lý khi hy vọng rằng định nghĩa hàm thu được z = 10.
Robert Dodier

@RobertDodier Nó kiểm tra các biến bên trong env đầu tiên, tức là trong hàm, tìm thấy nó và dừng tìm kiếm khác trong đó tức là trong env cha. Bạn có thể kiểm tra bằng cách đổi tên 'z' trong hàm tức là z1 <- 4trong hàm vàf(3)# [1] 16
hoạt động

Hoặc chỉ định môi trường tức là z <- 4; environment(g) <- .GlobalEnvvà sau đó gọiz <- 10 > f(3) [1] 16
từ

Câu trả lời:


9

R sử dụng phạm vi từ vựng có nghĩa là nếu một đối tượng được tham chiếu nhưng không được xác định trong hàm thì nó được tìm kiếm trong môi trường mà hàm được định nghĩa , không phải là môi trường mà nó được gọi.

z được tham chiếu trong g nhưng không được xác định bằng g nên nó nhìn vào môi trường trong đó g được xác định và đó là môi trường trong f nên g sử dụng z = 4.

Trên thực tế trong trường hợp này, môi trường mà g được định nghĩa giống như môi trường mà g được gọi vì vậy bất kỳ cách nào bạn nhìn vào nó z = 4 đều phải được sử dụng. Nếu các hàm được mặc định cho môi trường toàn cầu để tìm kiếm các đối tượng không được xác định trong hàm thì nó sẽ sử dụng z = 10 nhưng đó không phải là cách R hoạt động.

Làm cho nó hoạt động khác nhau

Nếu vì lý do nào đó bạn muốn buộc g tìm kiếm z trong môi trường mà f được gọi thì bạn có thể làm điều này (trong đó parent.frame()đề cập đến môi trường mà f được gọi).

f2 <- function(x, envir = parent.frame()) {
    g <- function(y) {
            y + with(envir, z)
    }
    z <- 4
    x + g(x)
 }
 z <- 10
 f2(3)
 ## [1] 16

hoặc chúng ta có thể sử dụng y + envir$zngoại trừ cái đó chỉ nhìn vào khung cha mẹ chứ không withnhìn vào tổ tiên của nó trong khi sẽ tìm trong tổ tiên của khung cha nếu không tìm thấy trong khung cha.

Một cách khác là thay đổi môi trường của g như thế này để nó nhìn vào envircác đối tượng không tìm thấy trong g:

f3 <- function(x, envir = parent.frame()) {
    g <- function(y) {
            y + z
    }
    environment(g) <- envir
    z <- 4
    x + g(x)
 }
 z <- 10
 f3(3)
 ## [1] 16
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.