2016-01-25 4 views
5

リスト要素のすべてのペアごとの組み合わせに関数を適用したいとします。 各要素は同じ長さのベクトルです。出力はn x nの行列形式、nはリストの要素数です。リスト要素のすべてのペアごとの組み合わせに関数を適用するR

は、以下の例を考えてみます

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

このループ作品が、それは遅いですし、出力が行列

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

任意のアイデアとしてフォーマットされていませんか?

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

私は@Aに興味を持っていました:

+2

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

+0

うわー!あなたの答えをありがとう、それはずっと速い;) – goclem

答えて

5

ネストされたsapplyは、トリックを行うだろう。 Webbのソリューション。外側のソリューションが少し速くなり小さいリストについては、これ

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 

が、大きなリストのためには、ネストされたsapplyソリューションは少し速くてもよいことに表示されます。ここではいくつかのベンチマークです。

関連する問題