- 取得連結
- X
- 以電子郵件傳送
- 其他應用程式
程式語言:R
官網
簡介:variable scope 與 傳遞
R 環境空間與函數
官網
簡介:variable scope 與 傳遞
Global vs. Local
function 內自成一區,為 Lexical scope
如下範例,進入 function 時,並看不到外部的 x,所以皆為 character(0)
所以更改的值,自然也無法反應到外部
但此時若想印出 x ,會發現仍有值,這是因為當發現無 x 時,會再往外找,直到 .GlobalEnv
強制指定
利用 <<- 將會直接往上層找符合的變數改變值,故原層的不變
若到 .GlobalEnv 都沒找到,則在 .GlobalEnv 建立新變數
package variable
如何指定 package 的變數
<package name>::<variable name>
所以更改的值,自然也無法反應到外部
但此時若想印出 x ,會發現仍有值,這是因為當發現無 x 時,會再往外找,直到 .GlobalEnv
f <- function() { print("In f") # 目前有的物件 print(ls()) # character(0) print(x) # [1] 10 x <- 100 g <- function() { print("In g") # 目前有的物件 print(ls()) # character(0) print(x) # [1] 100 x <- 1000 # 目前的環境 print(environment()) # <environment: 0x0000000017f504a0> #目前有的物件 print(ls()) # [1] "x" print(x) # [1] 1000 print("Out g") } g() # 目前的環境 print(environment()) # <environment: 0x0000000017f505b8> # 目前有的物件 print(ls()) # [1] "g" "x" print(x) # [1] 100 print("out f") } x <- 10 f() # 目前的環境 # 也就是 .GlobalEnv print(environment()) # 目前有的物件 print(ls()) # [1] "f" "x" print(x) # [1] 10 print(.GlobalEnv$x) # [1] 10 # result # [1] "In f" # character(0) # [1] 10 # [1] "In g" # character(0) # [1] 100 # <environment: 0x000000001218f368> # [1] "x" # [1] 1000 # [1] "Out g" # <environment: 0x0000000012190e90> # [1] "g" "x" # [1] 100 # [1] "out f" # <environment: R_GlobalEnv> # [1] "f" "x" # [1] 10 # [1] 10
強制指定
利用 <<- 將會直接往上層找符合的變數改變值,故原層的不變
若到 .GlobalEnv 都沒找到,則在 .GlobalEnv 建立新變數
f <- function() { print("In f") x <- list(a=10) g <- function() { print("In g") x <- list(a=1) # 直接往上層找 x,直到 .GlobalEnv x$a <<- 100 print(x$a) # [1] 1 print("Out g") } g() print(x$a) # [1] 100 print("out f") } x <- list(a=10) print(x$a) # [1] 10 f() print(x$a) # [1] 100 # result # [1] 10 # [1] "In f" # [1] "In g" # [1] 1 # [1] "Out g" # [1] 100 # [1] "out f" # [1] 10
package variable
如何指定 package 的變數
<package name>::<variable name>
ggplot2::diamonds # A tibble: 53,940 × 10 # carat cut color clarity depth table price x y z # <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl> #1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43 #2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31 #3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31 #4 0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63 #5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75 #6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48 #7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47 #8 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53 #9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49 #10 0.23 Very Good H VS1 59.4 61 338 4.00 4.05 2.39 # ... with 53,930 more rows
Mutable vs. Immutable
事實上幾乎所有 R objects 都是 immutable,除了 Reference class 等
如下範例,可以看到 R 的 list 傳遞為 call by value
替代方案
environments
每次呼叫都從設定的 env 讀值
RC(Reference class)
f <- function(x) { print("In f") x$a <- 100 g <- function(x) { print("In g") x$a <- 1000 print(x$a) # [1] 1000 print("Out g") } g(x) print(x$a) # [1] 100 print("out f") } x <- list(a=10) f(x) print(x$a) # [1] 10 # result # [1] "In f" # [1] "In g" # [1] 1000 # [1] "Out g" # [1] 100 # [1] "out f" # [1] 10
替代方案
environments
每次呼叫都從設定的 env 讀值
my.new.env <- new.env() f <- function() { print("In f") my.new.env$x$a <- 100 print(my.new.env$x$a) # [1] 100 print("out f") } my.new.env$x <- list(a=10) f() print(my.new.env$x$a) # [1] 100 # result # [1] "In f" # [1] 100 # [1] "out f" # [1] 100
RC(Reference class)
f <- function(x) { print("In f") x$a <- 100 print(x$a) # [1] 100 print("out f") } X <- setRefClass("X", fields=list(a='numeric')) x <- X(a=10) print(x$a) # [1] 10 f(x) print(x$a) # [1] 100 # result # [1] 10 # [1] "In f" # [1] 100 # [1] "out f" # [1] 100
參考
R Environment and ScopeR 環境空間與函數
留言
張貼留言