将函数应用于 R 中列表元素的所有成对组合
Posted
技术标签:
【中文标题】将函数应用于 R 中列表元素的所有成对组合【英文标题】:Apply a function to all pairwise combinations of list elements in R 【发布时间】:2016-05-02 03:23:25 【问题描述】:我想对列表元素的所有成对组合应用一个函数。
每个元素都是一个长度相同的向量。我想要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']]])
有什么想法吗?
【问题讨论】:
outer(l,l,Vectorize(foo))
【参考方案1】:
嵌套的 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 中列表元素的所有成对组合的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Matlab 中对两个向量应用二元函数以获得所有成对结果的矩阵?