Oto mój kod R. Funkcje są zdefiniowane jako:
f <- function(x, T) {
10 * sin(0.3 * x) * sin(1.3 * x ^ 2) + 0.001 * x ^ 3 + 0.2 * x + 80
}
g <- function(x, T, f=f) {
exp(-f(x) / T)
}
test <- function(g=g, T=1) {
g(1, T)
}
Błąd działania to:
> test ()
Błąd w test ():
obietnica już w trakcie oceny: rekurencyjne odwołanie do domyślnego argumentu lub wcześniejsze problemy?
Jeśli zastąpię definicję w definicji f
of g
, to błąd zniknie.
Zastanawiałem się, co to za błąd? Jak go poprawić, jeśli nie zastępują definicji f
w tym z g
? Dzięki!
Aktualizacja:
Dzięki! Dwa pytania:
(1) jeśli funkcja test
przyjmuje argument za f
, czy dodasz coś takiego test <- function(g.=g, T=1, f..=f){ g.(1,T, f.=f..) }
? W przypadkach z większą liczbą rekurencji dobrym i bezpiecznym sposobem jest dodawanie kolejnych . ?
(2) jeśli na przykład f
jest argumentem niefunkcjonalnym g <- function(x, T, f=f){ exp(-f*x/T) }
i test <- function(g.=g, T=1, f=f){ g.(1,T, f=f.) }
czy używanie tej samej nazwy zarówno dla formalnych, jak i faktycznych argumentów niefunkcjonalnych będzie dobrą i bezpieczną praktyką, czy może spowodować potencjalne problemy?
.....cumbersome
. :)...
lub listy do przekazywania argumentów w dół łańcucha funkcji. Jest dużo bardziej elastyczny (na dobre i na złe) niż wstępne definiowanie wszystkiego. Może się okazać, że po prostu będziesz musiał dodać kilka sprawdzeń, aby upewnić się, że oryginalne argumenty w elipsach (lub liście) są rozsądne.get("f", envir = parent.frame())
.Jeśli określisz kontekst oceny argumentów, unikniesz problemu o tej samej nazwie:
źródło
Podoba mi się odpowiedź G. Grothendiecka , ale zastanawiałem się, czy w twoim przypadku prostsze jest nie umieszczanie nazw funkcji w parametrach funkcji, na przykład:
źródło
Jak już wspomniano, problem wynika z posiadania argumentu funkcji zdefiniowanego jako sam. Chciałbym jednak dodać wyjaśnienie, dlaczego jest to problem, ponieważ zrozumienie, które doprowadziło mnie do łatwiejszego (dla mnie) sposobu uniknięcia problemu: po prostu podaj argument w wywołaniu zamiast definicji.
To nie działa:
ale to działa:
Argumenty funkcji istnieją w ich własnym środowisku lokalnym.
R szuka zmiennych najpierw w środowisku lokalnym, a następnie w środowisku globalnym. To jest tak, jak w przypadku, gdy zmienna wewnątrz funkcji może mieć taką samą nazwę jak zmienna w środowisku globalnym, a R użyje definicji lokalnej.
Posiadanie definicji argumentów funkcji w ich własnym środowisku lokalnym jest powodem, dla którego można mieć domyślne wartości argumentów oparte na innych wartościach argumentów, takich jak
Dlatego właśnie nie możesz DEFINIOWAĆ funkcji jako,
my.function <- function(x = x){}
ale możesz WYWOŁAĆ funkcję za pomocąmy.function(x = x)
. Kiedy definiujesz funkcję, R jest zdezorientowany, ponieważ znajduje argumentx =
jako lokalną wartośćx
, ale kiedy wywołujesz funkcję, R znajduje sięx = 4
w lokalnym środowisku, z którego dzwonisz.Więc oprócz naprawienia błędu poprzez zmianę nazwy argumentu lub jawne określenie środowiska, jak wspomniano w innych odpowiedziach, możesz również po prostu określić to
x=x
podczas wywoływania funkcji, a nie podczas jej definiowania. Dla mnie określenie, żex=x
w wywołaniu było najlepszym rozwiązaniem, ponieważ nie wymaga dodatkowej składni ani gromadzenia coraz większej liczby nazw zmiennych.źródło