2016-01-25 16 views
5

Desidero applicare una funzione a tutte le combinazioni a coppie di elementi di elenco. Ogni elemento è un vettore con la stessa lunghezza. Vorrei che l'output in un formato di matrice n x n, n fosse il numero di elementi nel mio elenco.Applicare una funzione a tutte le combinazioni a coppie degli elementi di elenco in R

consideri il seguente esempio:

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

questo ciclo funziona ma è lento e l'uscita non è formattata come matrice

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

Qualche idea?

+2

'outer (l, l, Vectorize (foo))' –

+0

Wow! Grazie per la tua risposta, è molto più veloce;) – goclem

risposta

5

Un sapply nidificato farebbe il trucco:

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

mi interessava @A. La soluzione di Webb. Ecco alcuni di benchmarking:

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 

Così per le liste più piccole la soluzione esterna è un po 'più veloce, ma per le liste più grandi sembra che la soluzione sapply nidificato può essere un po' più veloce.

Problemi correlati