在R中的矩阵行上应用函数

时间:2014-01-24 11:48:22

标签: r matrix apply

假设我有一个5乘7矩阵和一个函数f

a <- matrix(rnorm(7*5),5,7)
f <- function(x,y) sum(x+y)

我想计算矩阵b,其元素b[i,j]等于f(a[i,],a[j,])而没有for循环。我该怎么办?

2 个答案:

答案 0 :(得分:4)

您可以使用outer将函数应用于所有可能的组合:

rowNums <- seq(nrow(a)) # vector with all row numbers

outer(rowNums, rowNums, Vectorize(function(x, y) sum(a[x, ] + a[y, ])))

          [,1]      [,2]      [,3]       [,4]      [,5]
[1,]  6.319860 10.978305  6.911812  2.4609471 4.7021136
[2,] 10.978305 15.636751 11.570257  7.1193924 9.3605589
[3,]  6.911812 11.570257  7.503764  3.0528993 5.2940659
[4,]  2.460947  7.119392  3.052899 -1.3979658 0.8432008
[5,]  4.702114  9.360559  5.294066  0.8432008 3.0843673

修改

如果在使用rowSums之前计算outer,则计算效率会更高。此代码更短更快:

rs <- rowSums(a)

outer(rs, rs, "+")

          [,1]      [,2]      [,3]       [,4]      [,5]
[1,]  6.319860 10.978305  6.911812  2.4609471 4.7021136
[2,] 10.978305 15.636751 11.570257  7.1193924 9.3605589
[3,]  6.911812 11.570257  7.503764  3.0528993 5.2940659
[4,]  2.460947  7.119392  3.052899 -1.3979658 0.8432008
[5,]  4.702114  9.360559  5.294066  0.8432008 3.0843673

编辑2

解决您的实际问题(见评论):

ta <- t(a) # transpose

apply(a, 1, function(x) colSums(abs(ta - x)))

          [,1]      [,2]      [,3]     [,4]     [,5]
[1,]  0.000000 10.687579 10.933269 9.306339 7.763612
[2,] 10.687579  0.000000  7.465742 8.517358 7.847622
[3,] 10.933269  7.465742  0.000000 5.768676 6.851272
[4,]  9.306339  8.517358  5.768676 0.000000 6.687477
[5,]  7.763612  7.847622  6.851272 6.687477 0.000000

答案 1 :(得分:0)

一种方法是使用expand.grid创建子集索引并在此apply上使用:

matrix(apply(expand.grid(seq(nrow(a)),seq(nrow(a))),1,
  function(x) f(a[x[1],],a[x[2],])),nrow(a))
          [,1]       [,2]       [,3]      [,4]      [,5]
[1,] 8.9116431  4.1067161  0.6589584  3.681561  3.207056
[2,] 4.1067161 -0.6982109 -4.1459686 -1.123366 -1.597871
[3,] 0.6589584 -4.1459686 -7.5937263 -4.571123 -5.045629
[4,] 3.6815615 -1.1233656 -4.5711232 -1.548520 -2.023026
[5,] 3.2070558 -1.5978712 -5.0456289 -2.023026 -2.497531