2011-05-31 22 views
8

मानक आर अभिव्यक्ति outer(X, Y, f) एक मैट्रिक्स का मूल्यांकन करता है जिसका (i, j) -th प्रविष्टि मान f(X[i], Y[j]) है।बाहरी से एन आयामों को सामान्यीकृत कैसे करें?

मैं समारोह multi.outer को लागू करना चाहते हैं, outer की एक n आयामी सामान्यीकरण: multi.outer(f, X_1, ..., X_n), जहां च कुछ n-ary समारोह, एक (लंबाई (x_1) * ... * लंबाई (X_n)) का उत्पादन होगा सरणी जिसका (i_1, ..., i_n) - प्रत्येक प्रविष्टि में सभी मान्य इंडेक्स सेट (i_1, ..., i_n) के लिए मान f(X_1[i_1], ..., X_n[i_n]) है। जाहिर है, प्रत्येक I के लिए {1, ..., n} में, X_i के सभी तत्व multi.outer(f, X_1,...,X_i,..., X_n) में f फ़ंक्शन के लिए स्वीकार्य i-th तर्क होना चाहिए। मामले के लिए n = 2, multi.outerouter जैसा ही काम करेगा, हालांकि इसमें एक अलग हस्ताक्षर होगा (आईओयू, multi.outer(f, X, Y)outer(X, Y, f) के बराबर होगा)।

यह ध्यान रखना महत्वपूर्ण है कि, हालांकि तर्क X_1, ..., multi.outer का X_n सभी वैक्टर हैं, वे सभी आवश्यक मोड नहीं हैं। जैसे X_1 और X_2 क्रमश: c(1, 2, 3) और LETTERS[10:20] हो सकते हैं।

धन्यवाद!

उत्तर

16

यह एक तरीका है: सबसे पहले Vectorize और outer का प्रयोग कर एक समारोह है कि एक n आयामी मैट्रिक्स जहां प्रत्येक प्रविष्टि तर्कों की सूची है बनाता है परिभाषित करने के लिए जो दिया कार्य नहीं करेंगी पर लागू किया जा:

list_args <- Vectorize(function(a,b) c(as.list(a), as.list(b)), 
         SIMPLIFY = FALSE) 


make_args_mtx <- function(alist) { 
    Reduce(function(x, y) outer(x, y, list_args), alist) 
} 

अब multi.outer सिर्फ इस "आर्ग-मैट्रिक्स" पर apply और do.call आह्वान करने के लिए की जरूरत है:

0,123,
multi.outer <- function(f, ...) { 
    args <- make_args_mtx(list(...)) 
    apply(args, 1:length(dim(args)), function(a) do.call(f, a[[1]])) 
} 

एक उदाहरण समारोह के साथ इस कोशिश करते हैं:

fun <- function(a,b,c) paste(a,b,c) 

ans <- multi.outer(fun, LETTERS[1:2], c(3, 4, 5), letters[6:7]) 

> ans 
, , 1 

    [,1] [,2] [,3] 
[1,] "A 3 f" "A 4 f" "A 5 f" 
[2,] "B 3 f" "B 4 f" "B 5 f" 

, , 2 

    [,1] [,2] [,3] 
[1,] "A 3 g" "A 4 g" "A 5 g" 
[2,] "B 3 g" "B 4 g" "B 5 g" 
+0

अच्छा! यहां एक समान उत्तर के साथ एक समान (लेकिन जटिल नहीं) प्रश्न देखें: http: // stackoverflow।com/प्रश्न/5233308/है-वहाँ एक आर-समारोह-कि-लागू होता है एक समारोह करने के लिए प्रत्येक जोड़ी के- कॉलम/5233713 # 5233713 – Aaron

1

कैसे इस बारे में:


multi.outer<-function(f,...){ 

    apply(expand.grid(...),1,function(x){do.call(f,as.list(x))}) 

} 
+0

मेरा मानना ​​है कि ओपी चाहता था कि परिणाम एन-आयामी मैट्रिक्स में हो, प्रत्येक आयाम 'एफ' के प्रत्येक तर्क के अनुरूप होगा। 'Expand.grid' के बारे में मुझे जागरूक करने के लिए –

+0

+1, लेकिन जब मैंने परीक्षण' फ़ंक्शन (एस, बी, एल) {substr (एस, बी) के साथ इस 'multi.outer' (पहली बार) की कोशिश की, बी + एल -1)} ', और' सी ("एबीसीडीएफएचजी", "आईजेकेएलएमएनओपी", "क्यूआरएसटीयूवीडब्ल्यूएक्स"), 1: 5, 2: 3' बाकी तर्कों के रूप में, मुझे 'त्रुटि में कार्य मिला है, बी, एल): अप्रयुक्त तर्क (Var1 = "ABCDEFGH", Var2 = "1", Var3 = "2") '। मुझे यह पता लगाने का मौका नहीं मिला कि आपका कार्यान्वयन क्या करता है, या यह त्रुटि क्यों है। – kjo

0

मुझे लगता है कि हम इस का उपयोग करते हुए बाहरी और vectorize कर सकते हैं।

sigm = function(a=0,b=0,x){ 
return(exp(x*a+b)) 
} 

sigm1 = Vectorize(function(a=-1:1,b=-1:1,x){ 

outer(a,b,sigm,x) 
},SIMPLIFY = FALSE) 

अब, sigm1 (एक्स = 1: 3) आवश्यक उत्पादन देता

[[1]] 
     [,1]  [,2]  [,3] 
[1,] 0.1353353 0.3678794 1.000000 
[2,] 0.3678794 1.0000000 2.718282 
[3,] 1.0000000 2.7182818 7.389056 

[[2]] 
     [,1]  [,2]  [,3] 
[1,] 0.04978707 0.1353353 0.3678794 
[2,] 0.36787944 1.0000000 2.7182818 
[3,] 2.71828183 7.3890561 20.0855369 

[[3]] 
     [,1]  [,2]  [,3] 
[1,] 0.01831564 0.04978707 0.1353353 
[2,] 0.36787944 1.00000000 2.7182818 
[3,] 7.38905610 20.08553692 54.5981500 

केवल इस कोड स्निपेट के साथ वापस आकर्षित मैं एक = -1 के मूलभूत मूल्यों का उपयोग कर रहा है: 1 और बी = -1: 1। जब मैं फ़ंक्शन कॉलिंग के दौरान इसे पारित करने का प्रयास करता हूं, तो यह खराब हो जाता है। जैसे

sigm1(-1:1,-1:1,1:3) 

[[1]] 
     [,1] 
[1,] 0.1353353 

[[2]] 
[,1] 
[1,] 1 

[[3]] 
    [,1] 
[1,] 54.59815 

मैं यह समझने में असमर्थ हूं कि तर्कों को पारित करने से आउटपुट में यह अंतर क्यों आ रहा है।

संबंधित मुद्दे