zaten değerlendirilmekte olan söz: özyinelemeli varsayılan bağımsız değişken başvurusu veya önceki sorunlar?


143

İşte R kodum. Fonksiyonlar şu şekilde tanımlanır:

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)
}

Çalışan hata:

> test () test ()
hatası:
zaten değerlendirilmekte olan söz: özyinelemeli varsayılan bağımsız değişken başvurusu veya önceki sorunlar?

Ben tanımını yerine ise fo yer g, o zaman hata ortadan kalkar.

Hatanın ne olduğunu merak ediyordum? Tanımını ait yerine geçmez nasıl düzeltmek için fo içinde g? Teşekkürler!


Güncelleme:

Teşekkürler! İki soru:

(1) işlev testdaha ileri bir argüman alırsa f, benzer bir şey ekler misiniz test <- function(g.=g, T=1, f..=f){ g.(1,T, f.=f..) }? Daha fazla özyineleme olan durumlarda, daha fazlasını eklemek iyi ve güvenli bir uygulamadır . ?

(2) förneğin bir işlev olmayan argüman ise g <- function(x, T, f=f){ exp(-f*x/T) }ve test <- function(g.=g, T=1, f=f){ g.(1,T, f=f.) }hem resmi hem de gerçek işlevsel olmayan argümanlar için aynı adı kullanmak iyi ve güvenli bir uygulama mı yoksa bazı potansiyel sorunlara neden olabilir mi?

Yanıtlar:


159

Formun resmi argümanları buna x=xneden olur. Oluştukları iki örneği ortadan kaldırıyoruz:

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) {  ## 1. note f.
   exp(-f.(x)/T) 
}

test<- function(g. = g, T = 1) {  ## 2. note g.
   g.(1,T) 
}

test()
## [1] 8.560335e-37

2
Teşekkürler! İki soru (1) işlev testi f için bir argüman alırsa , test <- işlevi (g. = G, T = 1, f .. = f) {g. (1, T, f. = f ..)} ? Daha fazla özyineleme olan durumlarda, daha fazlasını eklemek iyi ve güvenli bir uygulamadır . ? (2) f işlev dışı bir argüman ise, örneğin g <- işlev (x, T, f = f) {exp (-f x / T)} * ve test <- işlevi (g. = G, T = 1, f = f) {g. (1, T, f = f.)} , Hem resmi hem de gerçek işlevsel olmayan argümanlar için aynı ismi kullanacak iyi ve güvenli bir uygulama mı yoksa bazı potansiyel sorunlara neden olabilir mi?
Tim

16
Başka çözüm var mı? Bazı argümanları fonksiyon zincirinin derinliklerinde (yaklaşık 5 seviye) geçiyorum ve bu çözüm olabilir .....cumbersome. :)
Roman Luštrik

2
@ RomanLuštrik Bağımsız değişkenleri aşağıya geçiriyorsanız ve bunların bazılarını güvenle yok sayabilirseniz ..., bağımsız değişkenleri işlev zincirinden geçirmek için elips veya bir liste kullanmaya bakın . Her şeyi önceden tanımlamaktan çok daha esnektir (iyi ve hasta için). Üç noktadaki (veya listedeki) orijinal argümanlarınızın mantıklı olduğundan emin olmak için bazı kontroller eklemeniz gerekebilir.
russellpierce

2
Buradaki başka bir seçenek, etkin vaatlerin yanlışlıkla zorlanmasını atlayarak, üst çerçevedeki bağımsız değişkenleri açıkça bulmaya çalışmaktır - ör get("f", envir = parent.frame()).
Kevin Ushey

1
Tek şart, sol ve sağ tarafta aynı adı kullanmamanızdır. Bunun dışında sadece stil.
G. Grothendieck

13

Bağımsız değişken değerlendirme bağlamını belirtirseniz, aynı addaki sorundan kaçınırsınız:

f <- function(x) {
  10 * sin(0.3 * x) * sin(1.3 * x ^ 2) + 0.001 * x ^ 3 + 0.2 * x + 80
}
g <- function(x, t=1, f=parent.frame()$f) {
  exp(-f(x) / t)
}
test <- function(g=parent.frame()$g, t=1) { 
  g(1,t)
}
test()
[1] 8.560335e-37

2
Bu benim çevreyi belirtmek düşünüyorum daha iyi bir yoludur daha açıktır
cloudscomputes

1

G. Grothendieck cevabını beğendim , ancak sizin durumunuzda fonksiyonların parametrelerine fonksiyon isimlerini dahil etmemenizin daha basit olduğunu merak ediyordum:

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) {
  exp(-f(x)/T) 
}
test<- function(T = 1) {
  g(1,T)
}
test()
## [1] 8.560335e-37

1

Daha önce de belirtildiği gibi, sorun kendisi olarak tanımlanan bir işlev argümanına sahip olmaktan kaynaklanmaktadır. Ancak, bunun neden bir sorun olduğunu açıklamak istiyorum, çünkü beni problemden kaçınmanın daha kolay (benim için) yoluna götüren anlayış: sadece çağrıda tanım yerine argümanı belirtin.

Bu çalışmıyor:

x = 4
my.function <- function(x = x){} 
my.function() # recursive error!

ancak bu işe yarar:

x = 4
my.function <- function(x){} 
my.function(x = x) # works fine!

İşlev bağımsız değişkenleri kendi yerel ortamlarında bulunur.

R değişkenleri önce yerel ortamda sonra da global ortamda arar. Bu, bir değişkenin bir işlev içinde genel ortamda bir değişkenle aynı ada sahip olabileceği gibidir ve R, yerel tanımı kullanacaktır.

İşlev bağımsız değişkeni tanımlarının kendi yerel ortamlarından oluşması, diğer bağımsız değişken değerlerine dayalı varsayılan bağımsız değişken değerlerine sahip olmanızın nedenidir.

my.function <- function(x, two.x = 2 * x){}

Bu nedenle bir işlevi tanımlayamazsınız, my.function <- function(x = x){}ancak işlevi kullanarak ARAYABİLİRSİNİZ my.function(x = x). İşlevi tanımladığınızda, R argümanını x =yerel değeri olarak bulduğu için karışır x, ancak R işlevini x = 4çağırdığınızda aradığınız yerel ortamda bulur .

Bu nedenle, bağımsız değişken adını değiştirerek veya ortamı diğer yanıtlarda belirtildiği gibi açıkça belirterek hatayı düzeltmenin yanı sıra x=x, işlevi tanımlamak yerine işlevi çağırdığınızda da belirtebilirsiniz . Benim için, x=xçağrıda en iyi çözüm olduğunu belirtmek , çünkü ekstra sözdizimi veya daha fazla değişken adı biriktirmek içermiyor.

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.