我想将一个函数应用于列表元素的所有成对组合。
每个元素都是一个长度相同的向量。我想要 n x n
中的输出矩阵格式,n
是我列表中的元素数量。
考虑以下示例:
# 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 可以解决问题:
sapply(l, function(x) sapply(l, function(y) foo(x,y)))
我对@A 感兴趣。韦伯的解决方案。这是一些基准测试:
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 解决方案可能要快一些。
关于r - 将函数应用于 R 中列表元素的所有成对组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34999019/