- 取得連結
- 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 環境空間與函數
留言
張貼留言