2013-07-18 10 views
5

Sandbox-ed tarzında bir R kodu öbeği çalıştırmaya çalışıyorum, gerekli tüm bağımlılıkları (işlevleri ve verileri) yeni bir ortama yükleyerek ve içindeki bir ifadeyi değerlendirerek ortamı. Ancak, ortamdaki diğer işlevleri çağıran işlevlerle ilgili sorun yaşıyorum. açıkça çevreyi takılarak Muhtemelen bir şey kaçırıyorumR - Ortamda iç içe geçmiş bir işlev değerlendirin

> attach(jobenv) 
> eval(expr) 
[1] 7 

çalışır oysa f1

> eval(expr, envir=jobenv) 
Error in f2(3) : could not find function "f1" 

bulamıyorum f2 beri expr üzerinde eval başarısız kullanma

jobenv <- new.env(parent=globalenv()) 
assign("f1", function(x) x*2, envir=jobenv) 
assign("f2", function(y) f1(y) + 1, envir=jobenv) 
expr <- quote(f2(3)) 

: İşte basit bir örnek Açık, ama ben çalışır eval çağrı herhangi bir permütasyon bulamadık. Çevreyi bağlamadan aynı etkiyi elde etmenin bir yolu var mı?

+1

Sen, düzenleme yeni bir soru yapmalıdır. –

+0

Öneriniz için teşekkürler, işte burada: [R - serileştirilmiş bir ortamda iç içe işlev çağrısını değerlendir] (http://stackoverflow.com/questions/17733323/r-evaluate-nested-function-call-in- inherits = TRUE' için –

cevap

7

Orada Bunu yapmanın birçok yolu vardır, ama ben tür gibi bu bir: o orijinal olandan çok farklı olduğundan

jobenv <- new.env(parent=globalenv()) 

local({ 
    f1 <- function(x) x*2 
    f2 <- function(y) f1(y) + 1 
}, envir=jobenv) 

## Check that it works 
ls(jobenv) 
# [1] "f1" "f2" 
local(f2(3), envir=jobenv) 
# [1] 7 
eval(quote(f2(3)), envir=jobenv) 
# [1] 7 
+1

+1 çok hoş. Her ne kadar fonksiyon tanımlarını bir '' '' '' '' '' içerisine yerleştirerek kısaltabilir ve daha genel hale getirebilirsiniz. –

+0

@JoshuaUlrich - İyi nokta. Teşekkürler.(Cevabınızı önerinizi içerecek şekilde düzenledim.) –

4

Kapsam, çağrıldığında değil, işlev oluşturulduğunda tanımlanır. section 10.7 of the Introduction to R kılavuzuna bakın.

Bu bana biraz garip geliyor, ama hep birlikte assign'dan kaçınsanız ve sadece $<- kullanın, aynı davranışı elde edersiniz.

jobenv <- new.env(parent=globalenv()) 
jobenv$f1 <- function(x) x*2 
jobenv$f2 <- function(y) f1(y) + 1 
expr <- quote(f2(3)) 
eval(expr, envir=jobenv) 

Bu f1 ve f2 kapatılmasının ortamı küresel çevre olduğu için gibi görünüyor. jobenv olmasını beklerdim.

> environment(jobenv$f1) 
<environment: R_GlobalEnv> 
> environment(jobenv$f2) 
<environment: R_GlobalEnv> 

bir çözüm açıkça her fonksiyonun ortamını ayarlamak için ... ama daha kolay bir yolu olmalı.

> environment(jobenv$f1) <- jobenv 
> environment(jobenv$f2) <- jobenv 
> eval(expr, envir=jobenv) 
[1] 7 
+0

+1; İtiraf etmeliyim ki, ilk önce oraya atanmadan önce 'f1' değişkeninin 'jobenv'de nasıl bulunduğunu göremiyorum. Belirtilen pasajda, kullanıcının çalışma alanına tahsis edilmek üzere, orada karşılaşılmayan sembolün olmasını beklerdim. –

+0

Şüpheci olmaya haklıymışım gibi görünüyor: İlk örneğiniz sadece f1 ve f2'yi global ortama atar. (Çalıştırdıktan sonra 'ls()' ve 'ls (jobenv) 'yi deneyin.) Ve ikinci örneğiniz de işe yaramıyor. –

+0

@ JoshO'Brien: Haklısınız. F- –