2014-09-09 19 views
8

'daki iki alt işlevine nasıl geçireceğimi bir dizi parametreyi bir işleve iletmeye çalışıyorum. Bu fonksiyon, yukarıdaki parametre setinin bir parçası olan iki alt fonksiyona sahiptir.Ebeveyn işlevindeki "..." parametrelerini r

f_combined(xx = 2, yy = 2) 

: Aşağıdaki "BASİTLEŞTİRİLMİŞ" Örneğin f_combined yılında

... Ben f_plus için xxf_sqr geçirilir ve yy geçirilecek şekilde aşağıdaki işlev çağrısı yapmak istiyorum götüren bir fonksiyonudur ama bana bir hata verir:

Error in f_sqr(...) : unused argument (yy = 2) 

herhangi bir suggustion s?

f_sqr <- function(xx =1){ 
    xx^2 
} 

f_plus <- function(yy =1){ 
    yy + 1 
} 

f_combined <- function(...){ 
    f_sqr(...) + f_plus(...) 
} 
+2

Eğer '...' kullanmak yerine kombine fonksiyonları varsayılan argümanlar koymak Can çağrıları vardır? – nico

+0

Gerçekten değil. Basit bir işlev için Evet, bunu yapabiliriz. Ancak, birçok işlevi birçok parametreyle potansiyel olarak birleştiren çok daha karmaşık bir işlev arıyorum. Ggplot() gibi bir işlevi düşünün. – kindadolf

cevap

9

arasında Alternatif bir işlev en formals() ne görmek sorgulamak istiyorum tarafından adlandırılmış ikili liste veya erişimi onu olarak erişim ... adlandırılmış parametreler bekliyor ve sadece bunlardan geçiyor. "Çocuk" işlevi ... kabul ederse, tüm argümanlar boyunca geçeriz. Bu yöntem, konumsal argümanlar için iyi çalışmaz.

f_combined <- function(..., .fns =list(f_sqr, f_plus), .reduce=`+`){ 
    dots <- list(...) 
    Reduce(.reduce, lapply(.fns, function(f) { 
     if ("..." %in% names(formals(f))) { 
      do.call(f, dots) 
     } else if (any(names(dots) %in% names(formals(f)))) { 
      do.call(f, dots[names(formals(f))]) 
     } else { 
      f() 
     } 
    })) 
} 

Burada ben bir parametre ( .fns=list(f_sqr, f_plus)) olarak çalışacak iki işlev kurdum böylece kolaylıkla değiştirilebilir veya daha fazla çaba harcamadan eklenebilir. Ayrıca, bu değerleri toplamı ( .reduce='+') dışında bir şey yapmak istediğinizde nasıl birleştireceğinizi belirten bir parametre belirledim. Ancak temel fikir, adlandırılmış parametrelerin en iyi kümesini bulur ve bunları geçirir. "Çocuk" fonksiyonunuzun parametreler için de varsayılan değerleri olduğundan, hiçbir parametreden geçmediğinizde de çalışırlar. İşte

bazı örnek

f_combined() 
# [1] 3 
f_combined(xx=2) 
# [1] 6 
f_combined(yy=2) 
# [1] 4 
f_combined(xx = 2, yy = 2) 
# [1] 7 
+0

Bu cevap için teşekkür ederiz. Benim için çok yararlı oldu. Sanırım biraz daha geliştirilebilir (f'den daha fazla argüman olduğunda ...): 'do.call (f, noktalar [kesişim (isimler (noktalar), isimler (formals (f)))])' – jmones

13

yapabilirsiniz ya sipariş ..n

f_sqr <- function(xx =1){xx^2} 
f_plus <- function(yy =1){yy + 1} 

f_combined <- function(...){ 
    print(f_sqr(list(...)$xx)) 
    print(f_plus(list(...)$yy)) 
    print(f_sqr(..1)) 
    print(f_plus(..2)) 
} 
f_combined(yy = 1, xx = 10) 

[1] 100 (element with name xx of the list ...) 
[1] 2 (element with name yy of the list ...) 
[1] 1 (the first argument in the list ...) 
[1] 11 (the second argument in the list ...) 

Çıktı ?"..."

10.4 The ‘...’ argument

Another frequent requirement is to allow one function to pass on argument settings to another. For example many graphics functions use the function par() and functions like plot() allow the user to pass on graphical parameters to par() to control the graphical output. (See The par() function, for more details on the par() function.) This can be done by including an extra argument, literally ‘...’, of the function, which may then be passed on. An outline example is given below.

fun1 <- function(data, data.frame, graph=TRUE, limit=20, ...) { 
    [omitted statements] 
    if (graph) 
    par(pch="*", ...) 
    [more omissions] 
} 

Less frequently, a function will need to refer to components of ‘...’. The expression list(...) evaluates all such arguments and returns them in a named list, while ..1, ..2, etc. evaluate them one at a time, with ‘..n’ returning the n'th unmatched argument.

+2

İki argümandan biri ihmal edilirse bu başarısız olur. Örneğin 'f_combined (yy = 1)' beklenen sonucu vermeyecektir. – nico

+0

@nico, OP, '' 'kullanmayı nasıl kullandığını sorduğundan, bu onu nasıl kullanacağımı anladım. İşte bu. MrFlick daha kararlı bir çözüm bulmuş gibi görünüyor. –

+0

Peki, her iki parametreyi belirtmeniz ve varsayılanları kullanmanız gerekmiyorsa, '' 'işlevini kullanmanın amacı nedir? Dürüst olmak gerekirse, bence yukarıda anlattığım gibi, 'f_combined <- function (xx = 1, yy = 2) 'dır ve varsayılan olarak iki diğer fonksiyona sahip olmanın en kolay yolu olduğunu düşünüyorum. – nico