2016-01-25 42 views
5

Chcę zastosować funkcję do wszystkich kombinacji parami elementów listy. Każdy element jest wektorem o tej samej długości. Chciałbym, aby dane wyjściowe w formacie matrycy n x n, n były liczbą elementów na mojej liście.Zastosuj funkcję do wszystkich kombinacji parami elementów listy w R

Rozważmy następujący przykład:

# 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) 

ta pętla działa, ale jest powolny i wyjście nie jest sformatowana jako matryca

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

Każdy pomysł?

+2

'zewnętrzny (l, l, wektoryzacja (foo))' –

+0

Wow! Dzięki za odpowiedź, jest to o wiele szybsze;) – goclem

Odpowiedz

5

Zagnieżdżona sapply by rade:

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

byłem zainteresowany @a. Rozwiązanie Webb. Oto analiza porównawcza:

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 

więc dla mniejszych list zewnętrzna rozwiązanie jest trochę szybciej, ale dla większych list wydaje się, że rozwiązanie sapply zagnieżdżone mogą być nieco szybciej.