2016-01-25 7 views
5

Ich möchte eine Funktion auf alle paarweisen Kombinationen von Listenelementen anwenden. Jedes Element ist ein Vektor mit der gleichen Länge. Ich möchte die Ausgabe in einem n x n Matrixformat, n ist die Anzahl der Elemente in meiner Liste.Anwenden einer Funktion auf alle paarweisen Kombinationen von Listenelementen in R

Betrachten Sie das folgende Beispiel:

# Generating data 
l <- list() 
for(i in 1:5) l[[i]] <- sample(0:9, 5, T) 

# Function to apply 
foo <- function(x, y) 1 - sum(x * y)/sqrt(sum(x^2) * sum(y^2)) 

# Generating combinations 
comb <- expand.grid(x = 1:5, y = 1:5) 

Diese Schleife funktioniert, aber es ist langsam und die Ausgabe wird nicht als Matrix

# Applying function 
out <- list() 
for(i in 1:nrow(comb)) { 
    out[[i]] <- foo(l[[comb[i, 'x']]], l[[comb[i, 'y']]]) 
} 

Jede Idee formatiert?

+2

'äußere (l, l, vektorisieren (foo))' –

+0

Wow! Danke für deine Antwort, es ist so viel schneller;) – goclem

Antwort

5

Eine verschachtelte sapply würde der Trick:

sapply(l, function(x) sapply(l, function(y) foo(x,y))) 

ich in @A interessiert war. Webb's Lösung. Hier sind einige Eckwerte:

R> for(i in 1:50) l[[i]] <- sample(0:9, 5, T) 
R> microbenchmark(sapply(l, function(x) sapply(l, function(y) foo(x,y))), outer(l,l,Vectorize(foo)), time=1000) 
Unit: nanoseconds 
                expr  min  lq 
sapply(l, function(x) sapply(l, function(y) foo(x, y))) 7493739 8479127.0 
          outer(l, l, Vectorize(foo)) 6778098 8316362.5 
                time  5  48.5 
     mean median  uq  max neval 
1.042e+07 1.027e+07 1.155e+07 17982289 100 
1.030e+07 1.002e+07 1.187e+07 16076063 100 
1.672e+02 1.385e+02 1.875e+02  914 100 

R> for(i in 1:500) l[[i]] <- sample(0:9, 5, T) 
R> microbenchmark(sapply(l, function(x) sapply(l, function(y) foo(x,y))), outer(l,l,Vectorize(foo)), times=100) 
Unit: milliseconds 
                expr min lq mean 
sapply(l, function(x) sapply(l, function(y) foo(x, y))) 677.3 768.5 820.4 
          outer(l, l, Vectorize(foo)) 828.6 903.0 958.3 
median uq max neval 
    815.9 842.7 1278 100 
    930.7 960.5 1819 100 

Also für kleinere Listen die äußere Lösung ein wenig schneller, aber für größere Listen scheint es, dass die verschachtelte sapply Lösung ein bisschen schneller sein kann.