2014-04-26 19 views
5

Tôi khá mới đối với R, nhưng đến từ Đề án - cũng bị lốm đốm và có đóng cửa - tôi hy vọng có thể biến đổi các biến bên ngoài trong một bao đóng.Biến đổi một biến trong một bao đóng

Ví dụ, trong

foo <- function() { 
    s <- 100 

    add <- function() { 
    s <- s + 1 
    } 

    add() 
    s 
} 

cat(foo(), "\n") # prints 100 and not 101 

Tôi mong chờ foo() trở lại 101, nhưng nó thực sự trở lại 100:

$ Rscript foo.R 
100 

Tôi biết rằng Python có global từ khóa để khai báo phạm vi của các biến (doesn 't làm việc với ví dụ này, mặc dù). R có cần một cái gì đó tương tự?

Tôi đang làm gì sai?

Cập nhật

Ah, là vấn đề mà trong add tôi đang tạo ra một mới, biến cục bộ s rằng bóng tối bên ngoài s? Nếu vậy, làm cách nào tôi có thể biến đổi s mà không tạo biến cục bộ?

+0

Người kiểm duyệt có thể đóng dưới dạng bản sao hoặc bạn có thể tham gia và bỏ phiếu để đóng thành viên. –

+0

@BondedDust Gotcha, tôi đã bỏ phiếu cho điều này để được đóng lại là tốt. Chỉ có vấn đề Googling cho nó --- Tôi thực sự không tìm thấy giải pháp cho đến khi tôi đăng ở đây. Vì vậy, các mod khác có thể quyết định phải làm gì với nó. – csl

+1

Hai phiếu bầu khác và nó sẽ bị đóng bất kể sự chú ý của người điều tiết. Bạn có thể thấy rằng cơ sở lớp học tham chiếu là một mô hình phù hợp với phong cách lập trình của bạn và sẽ không bị xem là nguy hiểm bởi việc sử dụng R bình thường. Nó sử dụng các môi trường có tên và cho phép bạn có một số tính năng của các biến "toàn cục". –

Trả lời

3

Sử dụng toán tử <<- để gán trong hàm add().

Từ ?"<<-":

Các nhà khai thác <<-->> thường chỉ được sử dụng trong các chức năng, và gây ra một tìm kiếm để thực hiện thông qua các môi trường cha mẹ cho một định nghĩa hiện của biến được giao. Nếu như một biến được tìm thấy (và ràng buộc của nó không bị khóa) thì giá trị của nó được định nghĩa lại, nếu không việc gán sẽ diễn ra trong môi trường toàn cục. Lưu ý rằng ngữ nghĩa của chúng khác với ngôn ngữ S, nhưng hữu ích khi kết hợp với các quy tắc phạm vi R. Xem sách hướng dẫn ‘Định nghĩa ngôn ngữ R’ để biết thêm chi tiết và ví dụ.

+0

Bạn nói "để chuyển nhượng". Tôi có nên * luôn luôn * sử dụng '<< -' để gán không? Chỉ sử dụng '<-' cho khai báo? – csl

+1

Chỉ khi bạn muốn truy cập một tên ràng buộc bên ngoài chức năng (nói không chính thức). Nếu không, bạn không nên sử dụng nó ở tất cả: nó khá "nguy hiểm". – gagolews

+0

Nó nói rằng '<< -' sẽ gán trong môi trường _global_ nếu nó không thể tìm thấy bất kỳ tham chiếu nào đi lên môi trường mẹ. Âm thanh đáng sợ với tôi, tôi hy vọng nó sẽ xác định nó _locally_ thay thế. Đây co phải vân đê? – csl

3

Bạn cũng có thể sử dụng assign và xác định phạm vi chính xác bằng cách sử dụng lập luận envir, hoạt động theo cách tương tự như <<- chức năng add của bạn trong trường hợp này nhưng làm cho ý định của bạn một chút rõ ràng hơn:

foo <- function() { 
    s <- 100 

    add <- function() { 
    assign("s", s + 1, envir = parent.frame()) 
    } 

    add() 
    s 
} 

cat(foo(), "\n") 

Tất nhiên cách tốt hơn cho loại điều này trong R là để hàm của bạn trả về biến (hoặc biến) nó sửa đổi và gán lại chúng một cách rõ ràng cho biến ban đầu:

foo <- function() { 
    s <- 100 
    add <- function(x) x + 1 
    s <- add(s) 
    s 
} 

cat(foo(), "\n") 
2

Dưới đây là một cách tiếp cận nhiều hơn nữa có thể là một ít an toàn hơn so với assign hoặc <<- phương pháp:

foo <- function() { 
    e <- environment() 
    s <- 100 

    add <- function() { 
     e$s <- e$s + 1 
    } 

    add() 
    s 
} 

foo() 

Việc chuyển nhượng <<- có thể gây ra vấn đề nếu bạn vô tình đánh sai tên biến của bạn, nó vẫn sẽ làm điều gì đó, nhưng nó sẽ không là những gì bạn đang mong đợi và có thể khó tìm ra nguồn gốc của vấn đề. Cách tiếp cận assign có thể phức tạp nếu bạn muốn di chuyển hàm cộng vào bên trong một hàm khác hoặc gọi hàm đó từ một hàm khác. Cách tiếp cận tốt nhất tổng thể là không có các hàm sửa đổi các biến bên ngoài phạm vi của chúng và có hàm trả về bất kỳ thứ gì quan trọng.Nhưng khi điều đó là không thể, phương pháp trên sử dụng phạm vi từ vựng để truy cập vào môi trường e, sau đó gán vào môi trường để nó sẽ luôn luôn chỉ định cụ thể vào hàm đó, không bao giờ ở trên hoặc bên dưới.

Các vấn đề liên quan