将函数应用于 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 中对两个向量应用二元函数以获得所有成对结果的矩阵?

如何在 Pyspark Dataframe 中创建多列的所有成对组合?

函数适用于列表的一个元素,不适用于完整列表,R

将矩阵值计算为 R 中列表中所有成对比较的平均值

将函数应用于列表的每个元素

如何将参数值列表应用于 R 中的函数?