R'deki küresel ve yerel değişkenler


126

Ben R için acemiyim ve R'de yerel ve global değişkenlerin kullanımıyla oldukça kafam karıştı.

İnternette , değişkeni mevcut ortamda kullanırsam =veya <-atarım ve <<-bir fonksiyonun içindeyken global bir değişkene erişebilirim diyen bazı yazıları okudum .

Bununla birlikte, hatırladığım kadarıyla, C ++ yerel değişkenler {}, parantez içinde bir değişken tanımladığınızda ortaya çıkar , bu yüzden bunun R için aynı olup olmadığını merak ediyorum? Veya yerel değişkenler kavramına sahip olduğumuz R'deki fonksiyonlar için mi ?

Küçük bir deney yaptım, bu sadece parantezlerin yeterli olmadığını, yanlış bir şey mi anlıyorum?

{
   x=matrix(1:10,2,5)
}
print(x[2,2])
[1] 4

Bu yanıtlara ek olarak çalıştırılacak bazı kodlar: globalenv(); globalenv() %>% parent.env; globalenv() %>% parent.env %>% parent.env,…
izomorfizmler

@izomorphismes Error: could not find function "%>%",. Bu başka bir görev şekli mi?
Aaron McDaid

1
R-help ile ilgili konu: "<< -" operatörü ne anlama geliyor? .
Henrik

2
@AaronMcDaid Merhaba, daha önce yanıt vermediğim için özür dilerim! Kimden require(magrittr). x | f1 | f2 | f3Sol ( f3( f2( f1( x ) ) )) yerine sağdaki ( ) işlevleri uygulamanın bir yoludur .
izomorfizmler

Yanıtlar:


153

Bir işlev içinde bildirilen değişkenler, o işlev için yereldir. Örneğin:

foo <- function() {
    bar <- 1
}
foo()
bar

aşağıdaki hatayı veriyor: Error: object 'bar' not found.

barGlobal bir değişken yapmak istiyorsanız şunları yapmalısınız:

foo <- function() {
    bar <<- 1
}
foo()
bar

Bu durumda barfonksiyonun dışından erişilebilir.

Ancak, C, C ++ veya diğer birçok dilden farklı olarak, parantezler değişkenlerin kapsamını belirlemez. Örneğin, aşağıdaki kod parçacığında:

if (x > 10) {
    y <- 0
}
else {
    y <- 1
}

yif-elseifadeden sonra erişilebilir durumda kalır .

Sizin de söylediğiniz gibi iç içe ortamlar da oluşturabilirsiniz. Bunları nasıl kullanacağınızı anlamak için bu iki bağlantıya göz atabilirsiniz:

  1. http://stat.ethz.ch/R-manual/R-devel/library/base/html/environment.html
  2. http://stat.ethz.ch/R-manual/R-devel/library/base/html/get.html

Burada küçük bir örnek var:

test.env <- new.env()

assign('var', 100, envir=test.env)
# or simply
test.env$var <- 100

get('var') # var cannot be found since it is not defined in this environment
get('var', envir=test.env) # now it can be found

136

<- mevcut ortamda atama yapar.

Bir fonksiyonun içindeyken, R sizin için yeni bir ortam yaratır. Varsayılan olarak, oluşturulduğu ortamdaki her şeyi içerir, böylece bu değişkenleri de kullanabilirsiniz, ancak oluşturduğunuz yeni hiçbir şey küresel ortama yazılmayacaktır.

Çoğu durumda <<-, halihazırda global ortamda bulunan değişkenlere atanacak veya bir fonksiyonun içinde olsanız bile global ortamda bir değişken oluşturacaktır. Ancak, bu kadar kolay değil. Yaptığı şey, ilgili adı olan bir değişken için ana ortamı kontrol etmektir. Üst ortamınızda bulamazsa, üst ortamın üst ortamına (işlevin oluşturulduğu anda) gider ve oraya bakar. Küresel ortama doğru devam eder ve küresel ortamda bulunmazsa değişkeni küresel ortamda atar.

Bu neler olup bittiğini gösterebilir.

bar <- "global"
foo <- function(){
    bar <- "in foo"
    baz <- function(){
        bar <- "in baz - before <<-"
        bar <<- "in baz - after <<-"
        print(bar)
    }
    print(bar)
    baz()
    print(bar)
}
> bar
[1] "global"
> foo()
[1] "in foo"
[1] "in baz - before <<-"
[1] "in baz - after <<-"
> bar
[1] "global"

fooHenüz aramadığımız çubuğu ilk kez yazdırdığımızda, bu hala küresel olmalı - bu mantıklı. İkinci kez fooçağırmadan önce içine yazdırdığımızda baz"in foo" değeri mantıklıdır. Aşağıdakiler <<-aslında ne yaptığını gördüğümüz yerdir . Print ifadesi. 'Den sonra gelse de yazdırılan bir sonraki değer "baz - önce << -" dir <<-. Bunun nedeni <<-, mevcut ortama bakmamasıdır (küresel ortamda olmadığınız sürece bu durumda <<-davranır <-). Yani bazbar değerinin içi "baz - << - öncesi" olarak kalır. bazBarın içindeki kopyası dediğimizde foo"bazda" olarak değiştirilir ama gördüğümüz gibi global bardeğişmez.bariçinde tanımlanırfooYarattığımız zaman ebeveyn ortamında olduğu bazbu ilk kopyasıdır böylece baro <<-görür ve böylece atar kopyalayın. Yani <<-doğrudan küresel ortama atanmak değil.

<<-aldatıcıdır ve önleyebiliyorsanız kullanmanızı tavsiye etmem. Gerçekten global ortama atamak istiyorsanız, atama işlevini kullanabilir ve genel olarak atamak istediğinizi açıkça söyleyebilirsiniz.

Şimdi <<-, atama ifadesini değiştiriyorum ve bunun hangi etkiye sahip olduğunu görebiliriz:

bar <- "global"
foo <- function(){
    bar <- "in foo"   
    baz <- function(){
        assign("bar", "in baz", envir = .GlobalEnv)
    }
    print(bar)
    baz()
    print(bar)
}
bar
#[1] "global"
foo()
#[1] "in foo"
#[1] "in foo"
bar
#[1] "in baz"

Yani her iki seferde foode değerin içine bar yazdırırız , çağırdıktan sonra bile "in foo" olur baz. Bunun nedeni , foo'nun içi assignkopyasını hiç düşünmemiş barolmamızdır çünkü ona tam olarak nereye bakacağımızı söylemiştik. Ancak, bu sefer global ortamdaki bar değeri değiştirildi çünkü oraya açıkça atamıştık.

Şimdi ayrıca yerel değişkenler oluşturmayı da sordunuz ve bunu oldukça kolay bir şekilde bir işlev oluşturmadan da yapabilirsiniz ... Sadece localişlevi kullanmamız gerekiyor .

bar <- "global"
# local will create a new environment for us to play in
local({
    bar <- "local"
    print(bar)
})
#[1] "local"
bar
#[1] "global"

2

Aynı çizgide biraz daha

attrs <- {}

attrs.a <- 1

f <- function(d) {
    attrs.a <- d
}

f(20)
print(attrs.a)

"1" yazdıracak

attrs <- {}

attrs.a <- 1

f <- function(d) {
   attrs.a <<- d
}

f(20)
print(attrs.a)

"20" yazdıracak

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.