2014-09-23 20 views
5

, düşünün:nasıl kontrol edileceğini modifiye fonksiyon formallerin şeyleri kırmak için benim bitmeyen arayışı içinde

gbar<-function(x,y,x,a) x+2*y-4*a 
Error: repeated formal argument 'x' on line 1 

R düzgün yasadışı Formaller benim tanımlanmış bir işlev denetler.

Ama yukarı el faul şeyler eğer:

ffoo<-function(x,y,a) x+2*y-4*a 
formals(ffoo)<-c(x=7, formals(ffoo)) 

Sonra sadece bir şey geçersiz belirli koşullar altında bulacaksınız. ffoo(3,4,5,6)ffoo(y=3,a=2) gibi düzgün bir şekilde (muhtemelen beklediğim cevabı vermemekle birlikte) çalışacaktır; ffoo(x=5,y=3,a=2), belirsiz argüman adlarıyla ilgili bir hata verir.

Yani: var olan bir işlevin formals kontrolünü 'akıl' yapmak için bir işlevi olan herhangi bir base-R veya gelişmiş yardımcı paket var mı?

+1

ancak C okuyabilir [src/main/gram.y] adresindeki kodu (https://github.com/wch/r-source/blob/cf829c12299b8571cd67e9d8aae88ac31450c73c/src/main/gram.y). "CheckFormalArgs()" – Andrie

+1

@RichardScriven No işlevini arayın, yr cevabını kabul ettim. Son çözümüm, “formal” lerdeki gerçek isimleri karşılaştırmak ve maçlardan bir “do.call” oluşturmaktı. Bunu bir "yanıt-uzantısı" olarak göndereceğim –

cevap

4

Düzenleme: sadece çoğaltılmış bağımsız değişkenler için kontrol etmek istiyorsanız

, bunu yapabilirsiniz:

any(duplicated(names(formals(ffoo)))) 
# [1] TRUE 

Hadley aşağıda ikinci yorumunda bahseder gibi, dput() vermek garanti edilmez Bir fonksiyonun iyi/eksiksiz bir temsilini, yani orijinal cevabımda tarif edilen yaklaşımın (aşağıda yerine) başarısız olduğu fonksiyonlar olabilir.


Orjinal cevap: the C code pointed to by Andrie içinde ima gibi

, bu (değerlendirirken değil) function() için bir çağrı ayrıştırılırken R gerçekleştirir görünüşte bir çek. Bu nedenle, formals<- numaralı telefondan aramanızla ilgili kontrolden geçebildiniz ve bu yüzden aşağıdaki (örneğin) kontrol edilmemesinin de sebebi budur. Her iki durumda da, işlev function() aramasına ayrılmadan değiştirilir/oluşturulur.

eval(call("function", formals(ffoo), body(ffoo))) 
# function (x = 7, x, y, a) 
# x + 2 * y - 4 * a 

R'ın ayrıştırma makineleri genellikle kullanıcı tarafından görülebilen R fonksiyonları açığa çıkmadığı, bu yüzden bu denetimi gerçekleştirmek için hiçbir hazır fonksiyon R fonksiyonu var tahmin ediyorum. Yine de, R ifadesinin, ifadeyi oluşturduğunuzda veya komut satırında bir komut satırında girerek, karakter tanımlamasına karakter tanımlamasını dönüştürerek ve sonra yeniden ayrıştırmayı denediğinizde, aynı denetim kümesini gerçekleştirebilirsiniz. bir fonksiyonu olarak kontrol tamamlamayı için

parse(text = capture.output(dput(ffoo))) 
# Error in parse(text = capture.output(dput(ffoo))) : 
# repeated formal argument 'x' on line 1 

böyle bir şey yapmak:

İşte genel bir fikir Ben bir R fonksiyonu bulamıyor

isParseableFunction <- function(x) { 
    tryCatch(is.function(x) & 
      is.expression(parse(text = capture.output(dput(x)))), 
      error = function(e) FALSE) 
} 

isParseableFunction(data.frame) 
# [1] TRUE 
isParseableFunction(mean) 
# [1] TRUE 
isParseableFunction(ffoo) 
# [1] FALSE 
isParseableFunction(99) 
# [1] FALSE 
+0

Neden sadece niçin 'çoğaltılmış' (isimler (ffoo))) '' a bakmıyoruz? – hadley

+0

@ hadley-- Bu (ya da aslında, herhangi bir (çoğaltılmış (yöntemler :: formalArgs ("ffoo"))))) benim de ilk düşüncemdi, ama başka bir potansiyel bilinci yerine getirecek bir çözüm vermeye karar verdim. Bana-R gerçekleştirir kontrol eder. (İşte bu yüzden benim cevabım, "R'nin [...]" ile tam olarak aynı kontrolleri gerçekleştirdiğinden bahseder.) –

+0

Sorun şu ki, 'dput()' a karşı size işlevin iyi bir temsilini sunacak şekilde ticaret yapıyorsunuz - I Geçmişte yeterince problemim vardı, ona çok güvenmiyorum. – hadley

İlgili konular