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