[英]R : how to run a command between every pair in a list
我有一个nxm矩阵,如下所示:
df =
1 0 2 1
1 2 3 2
3 3 1 0
2 2 2 1
1 2 3 1
我想在所有列上运行一个函数,例如myfunct
,它将对每一列求和,然后对每对列求和,包括自包含。
16 17 19 13
17 18 20 14
19 20 22 16
13 14 16 10
有没有一种简单的方法将myfunct
应用于矩阵以得到相应的方阵? 更一般地说,有一个简单的方法,如果我有一个N事项的列表,在该列表中的所有i,j对之间运行双变量函数,输出为方矩阵?
这是一个快速功能:
myfun <- function(df){
z <- colSums(df)
matrix(rowSums(expand.grid(z, z)), ncol = ncol(df))
}
它首先将colSums
作为z
。 然后我们使用expand.grid
将z
所有组合带到z
并获取rowSums
。 输出被强制转换为具有正确列数的矩阵。
myfun(df)
[,1] [,2] [,3] [,4]
[1,] 16 17 19 13
[2,] 17 18 20 14
[3,] 19 20 22 16
[4,] 13 14 16 10
对于你想要做的事情,一般来说,一个很好的功能是Kronecker产品(在你的情况下,Kronecker总和)。 所以我们可以从定义方形Kronecker总和开始:
kronsum2 <- function(x) kronecker(x, x, FUN = "+")
有了这个,我们可以做到:
> matrix(kronsum2(colSums(df)), ncol = ncol(df))
[,1] [,2] [,3] [,4]
[1,] 16 17 19 13
[2,] 17 18 20 14
[3,] 19 20 22 16
[4,] 13 14 16 10
所以,如果你想写myfun
,那就是:
myfun <- function(M) matrix(kronsum2(colSums(M)), ncol=ncol(M))
并且它比expand.grid
更快启动!
set.seed(12083)
M <- matrix(runif(1e7),ncol=100)
library(microbenchmark)
> microbenchmark(times=100L,
myfun_mikec(M),
myfun_jeremy(M))
Unit: milliseconds
expr min lq mean median uq max neval
myfun_mikec(M) 8.326119 8.379396 8.514566 8.415031 8.578411 9.559709 100
myfun_jeremy(M) 8.869437 8.939920 9.058844 8.974743 9.049183 11.425142 100
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.