Piszę niektóre funkcje do wykonywania powtarzających się zadań, ale staram się zminimalizować ilość razy, kiedy ładuję dane. Zasadniczo mam jedną funkcję, która pobiera pewne informacje i tworzy fabułę. Następnie mam drugą funkcję, która przejdzie w pętlę i wypisze wiele wykresów do pliku .pdf. W obu tych funkcjach Mam następujący wiersz kodu:Zagnieżdżone środowisko wyboru funkcji
if(load.dat) load("myworkspace.RData")
gdzie load.dat
jest logiczne, a dane potrzebne są przechowywane w myworkspace.RData. Kiedy wywołuję funkcję wrappera, która wykonuje pętle i generuje wiele wykresów, nie chcę ponownie ładować obszaru roboczego w każdym wywołaniu funkcji wewnętrznej. Pomyślałem, że mógłbym załadować przestrzeń roboczą raz w funkcji opakowania, wtedy wewnętrzna funkcja mogłaby uzyskać dostęp do tych danych, ale dostałem błąd stwierdzający inaczej.
Moje zrozumienie było wtedy, gdy funkcja nie może znaleźć zmiennej w swoim środowisku lokalnym (utworzonej po wywołaniu funkcji), funkcja będzie wyglądać dla środowiska macierzystego dla zmiennej.
Założono, że środowisko macierzyste do wewnętrznego wywołania funkcji będzie zewnętrznym wywołaniem funkcji. Oczywiście nie jest to prawda:
func1 <- function(...){
print(var1)
}
func2 <- function(...){
var1 <- "hello"
func1(...)
}
> func2()
Error in print(var1) : object 'var1' not found
Po przeczytaniu liczne pytania, podręcznik języka i this bardzo pomocny blogu, wpadłem na następujący:
var1 <- "hello"
save(list="var1",file="test.RData")
rm(var1)
func3 <- function(...){
attach("test.RData")
func1(...)
detach("file:test.RData")
}
> func3()
[1] "hello"
Czy istnieje lepszy sposób to zrobić to? Dlaczego func1
nie szuka niezdefiniowanych zmiennych w lokalnym środowisku utworzonym przez func2
, gdy był func2
, który nazywał się func1
?
Uwaga: Nie wiedziałem, jak nazwać to pytanie. Jeśli ktoś ma lepsze sugestie, zmienię go i zredaguję tę linię.
Lexical scopingu oznacza, że funkcja będzie szukać niezdefiniowanych symboli w jego otoczeniu dominującej, która niekoniecznie jest środowisko dzwoni. Sprawdź również: https://github.com/hadley/devtools/wiki/Environments –
@ Ferdinand.kraft Dzięki za link. Przejdę przez to dziś po południu. – dayne
Jeśli twoje dane mają postać ramek danych, możesz użyć pakietu 'data.table' i przekazać tabele jako argument funkcji' func1' wewnątrz 'func3'. Ten pakiet działa przez odniesienie i nie tworzy niechcianych kopii danych. –