2013-05-16 28 views
9

Zastanawiam się, czy istnieje, aby uzyskać środowisko zadeklarowanej zmiennej. Powiedzmy, że już zadeklarowałem zmienną do środowiska i chcę użyć środowiska tej zmiennej do zadeklarowania jeszcze kilku zmiennych. Coś jak getenv („zmienna”)Jak uzyskać środowisko zmienne w R

+1

Dlaczego tego potrzebujesz? Może możemy zaproponować lepsze rozwiązanie. Byłbym ostrożny, pracując w ten sposób, tworząc sieć środowiska, w której relacje między nimi mogą być naprawdę trudne do zrozumienia i debugowania. Po prostu użyłbym zestawu funkcji i przekazałbym wszelkie potrzebne informacje za pomocą argumentów wejściowych. –

+2

Możesz użyć 'find', ale tylko wtedy, gdy środowisko jest" dołączone "do ścieżki wyszukiwania. – James

+0

Chciałem, aby niektóre zmienne miały określone środowisko. Jako czek, chciałem sprawdzić, czy dwie zmienne mają to samo środowisko. Coś jak część mojego zestawu testów RUnit. Pomyślałem tylko, że skoro mamy opcję dawania środowisk podczas korzystania z funkcji przypisania, to powinien istnieć łatwy sposób na uzyskanie przypisanego środowiska, a ja dodałbym, że czek to wszystko. Nic nie jest krytyczne. – Avinash

Odpowiedz

5

można uzyskać wszystkie obiekty w obszarze roboczym z ls(), więc można następnie sprawdzić, które z nich są środowiskach:

envirs <- ls()[sapply(ls(), function(x) is.environment(get(x)))] 

muszę korzystać get() tam, bo ls() zwrotów imiona postaci obiektów, a nie same obiekty. Teraz podając jakiś obiekt x, chcemy znaleźć, w którym środowisku istnieje. Wszystko, co musimy zrobić, to wykonać iterację w każdym środowisku w envirs i sprawdzić, czy zawierają one obiekt, którego szukamy. Coś wzdłuż linii (sprawdzanie zmiennej x):

sapply(envirs, function(e) 'x' %in% ls(envir=get(e))) 

Oto funkcja, aby to wszystko zrobić:

getEnv <- function(x) { 
    xobj <- deparse(substitute(x)) 
    gobjects <- ls(envir=.GlobalEnv) 
    envirs <- gobjects[sapply(gobjects, function(x) is.environment(get(x)))] 
    envirs <- c('.GlobalEnv', envirs) 
    xin <- sapply(envirs, function(e) xobj %in% ls(envir=get(e))) 
    envirs[xin] 
} 

To jest mniej więcej to samo, co ja robiłem na zewnątrz funkcja. gobjects czyta od ls(), tym razem jawnie sprawdzając globalne środowisko .GlobalEnv, ponieważ znajduje się teraz w funkcji.

envirs jest taki sam jak wcześniej, z wyjątkiem tego, że sprawdzi także .GlobalEnv. xin przechowuje których nazwy fotochemicznej x znajdowały się w linii.

xobj <- deparse(substitute(x)) 

Umożliwia badanego wyrobu bez cytatami np getEnv(x) kontra getEnv('x'). Jest to jednak kwestia preferencji, ale możesz ją zmienić, aby akceptowała znaki.


Oto kilka testów.

x1 <- 1 
getEnv(x1) 
# ".GlobalEnv" 

x2 <- 2.1 
e2 <- new.env() 
assign('x2', 2.2, e2) 
getEnv(x2) 
# ".GlobalEnv" "e2" 

e3 <- new.env() 
assign('x3', 3, e3) 
getEnv(x3) 
# "e3" 

ta sprawdza tylko środowiska tworzone w .GlobalEnv. Jestem pewien, że możesz opracować, jak go rozszerzyć, aby przeszukać więcej środowisk, jeśli tego potrzebujesz.

Jestem zaskoczony, że nie ma w tym wbudowanej funkcji. A może jest i nie wiem o tym. Nigdy wcześniej nie musiałem robić czegoś takiego, więc może to wcale nie jest zaskakujące.

+0

Po pierwsze, dodałbym 'all = TRUE' do twoich wywołań' ls'. Następnie rekurencyjnie tworzyłem środowiska wyszukiwania 'getEnv'. Wciąż jednak nie sprawdza środowisk nie związanych ze zmiennymi, takich jak środowiska stworzone do oceny zamknięcia. Przykład uruchomić to w konsoli: 'f <- function (x) {hidden <- x; function() {hidden << - hidden + 1; hidden}}; ' ' g <- f (0); ' ' as.list (environment (g)) ' –

+1

Ponadto, listy mogą mieć środowiska jako elementy, mogą występować środowiska czające się w atrybutach dowolnego obiektu itp. –

+0

@MadScone Dzięki za odpowiedź i wszystkim innym! Nawet jestem zaskoczony, że nie ma w tym żadnej wbudowanej funkcji. Ostatecznie zdecydowałem, że nie będę mieć tego czeku, ale dzięki za poświęcony czas. – Avinash

0

Jak o tym:

getEnvOf <- function(what, which=rev(sys.parents())) { 
    for (frame in which) 
    if (exists(what, frame=frame, inherits=FALSE)) 
     return(sys.frame(frame)) 
    return(NULL) 
} 

Wtedy możemy:

x <- 1 
getEnvOf("x") 
# <environment: R_GlobalEnv> 

getEnvOf("y") 
# NULL 

f <- function() getEnvOf("x") 
f() 
# <environment: R_GlobalEnv> 

g <- function() { x <- 2; getEnvOf("x") } 
g() 
# <environment: 0x114c26518> 
+1

Dobra funkcja odpowiadająca na pytanie. Poza zakresem pytania wydaje się, że istnieją pewne ograniczenia, o których należy pamiętać, np. sol. 'warning (" oops "); getEnvOf (" last.warning ")' daje 'NULL' natomiast' pryr :: where ("last.warning") 'powoduje' 'environment: base>'. Twoja funkcja wyszukuje w obrębie ścieżki wyszukiwania załączonych pakietów, ale w ramkach bieżącego stosu połączeń (jak już wspomniano, nie było o to pytane w pytaniu, ale inni użytkownicy powinni być tego świadomi). –

6

Patrz: http://adv-r.had.co.nz/Environments.html#env-basics

library(pryr) 
x <- 5 
where("x") 
#> <environment: R_GlobalEnv> 
where("mean") 
#> <environment: base> 

WHERE funkcja jest opisana w powyższej stronie internetowej. Znajduje tylko pierwsze środowisko, w którym pojawia się zmienna, ale można je łatwo zmodyfikować, aby znaleźć wszystko.