简体   繁体   English

R:从矩阵中提取相对于行/列位置的值

[英]R: Extract values from matrix relative to row/column position

My problem is as follows: Suppose we have a quadratic n*n matrix, eg我的问题如下:假设我们有一个二次 n*n 矩阵,例如

m <- matrix(runif(n^2), n,n)

Now I want to define a function f=function(k) that returns the sum of all matrix entries for which the sum of their row and column number weakly exceeds k.现在我想定义一个函数f=function(k) ,它返回所有矩阵条目的总和,其行数和列数的总和略超过 k。 For example, consider the 3*3 matrix例如,考虑 3*3 矩阵

m.ex <- matrix(1:9, 3,3, byrow = T)

which looks like看起来像

1 2 3
4 5 6
7 8 9

Then f(2) should give 45 = 1+2+3+4+5+6+7+8+9 (as for every entry in the matrix, the sum of the row and column position weakly exceeds 2), f(4) = 38 = 3+5+6+7+8+9 (as the sum of the row and column position weakly exceeds 4 for positions (1,3), (2,2), (2,3), (3,1), (3,2), and (3,3)), and f(5) = 23 = 6 + 8 + 9 (as the sum of the row and columin position weakly exceeds 5 for positions (2,3), (3,2), and (3,3)).那么 f(2) 应该给出 45 = 1+2+3+4+5+6+7+8+9(对于矩阵中的每个条目,行和列位置的总和弱超过 2),f( 4) = 38 = 3+5+6+7+8+9(因为对于位置 (1,3), (2,2), (2,3), ( 3,1)、(3,2) 和 (3,3)) 和 f(5) = 23 = 6 + 8 + 9(因为对于位置 (2, 3)、(3,2) 和 (3,3))。 Etc.等等。

Without loops, hope it's useful.没有循环,希望它有用。

library(reshape2)

#easy way to get all row and column indexes is to transform matrix to long
#has advantage of allowing vectorized computation and avoiding for-loops
myfun <- function(k, mm){
  #reshape matrix to easily get column and row numbers
  melt_m <- melt(mm, varnames=c("row","col"))
  #add row and col indixes
  melt_m$sum_row_col <- melt_m$row + melt_m$col
  #calculate result and return (sum of value when sum of rowcol>=k)
  return(sum(melt_m$value[melt_m$sum_row_col>=k]))
}

#example 1
test_m <- matrix(1:9,3,3,byrow=T)


> myfun(k=2,mm=test_m)
[1] 45
> myfun(k=4, mm=test_m)
[1] 38

Example of what melt does with a matrix:熔体对矩阵的作用示例:

> test_m
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
> melt(test_m,varnames=c("row","col"))
  row col value
1   1   1     1
2   2   1     4
3   3   1     7
4   1   2     2
5   2   2     5
6   3   2     8
7   1   3     3
8   2   3     6
9   3   3     9

The row and column functions make this way simpler than the other solutions, if I understand correctly:如果我理解正确的话, rowcolumn函数使这种方式比其他解决方案更简单:

f <- function(k, m) sum(m[row(m) + col(m) >= k])

For your m.ex :对于您的m.ex

sapply(c(2, 4, 5), f, m = m.ex)
# [1] 45 38 23

For larger examples:对于更大的例子:

set.seed(1230)
n <- 8
> print(round(m <- matrix(runif(n^2), nrow = n), 2))
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 0.57 0.87 0.94 0.98 0.87 0.66 0.16 0.98
[2,] 0.65 0.79 0.68 0.74 0.12 0.65 0.56 0.73
[3,] 0.76 0.85 0.71 0.45 0.64 0.45 0.12 0.55
[4,] 0.26 0.09 0.67 0.66 0.58 0.48 0.54 0.20
[5,] 0.38 0.63 0.27 0.16 0.20 0.96 0.05 0.90
[6,] 0.49 0.48 0.71 0.32 0.46 0.98 0.17 0.96
[7,] 0.91 0.99 0.97 0.98 0.84 0.21 0.21 0.44
[8,] 0.62 0.08 0.80 0.88 0.85 0.30 0.61 0.42
> f(12, m)
[1] 8.028652

This can be confirmed by noting the entries you denote are those in the lower-right triangle:这可以通过注意您表示的条目是右下角三角形中的条目来确认:

   *    *    *    *    *    *    *    *
   *    *    *    *    *    *    *    *
   *    *    *    *    *    *    *    *
   *    *    *    *    *    *    * 0.20
   *    *    *    *    *    * 0.05 0.90
   *    *    *    *    * 0.98 0.17 0.96
   *    *    *    * 0.84 0.21 0.21 0.44
   *    *    * 0.88 0.85 0.30 0.61 0.42

So the sum is 0.88+0.84+0.85+0.98+0.21+0.3+0.05+0.17+0.21+0.61+0.2+0.9+0.96+0.44+0.42 which is about 8.03.所以总和是0.88+0.84+0.85+0.98+0.21+0.3+0.05+0.17+0.21+0.61+0.2+0.9+0.96+0.44+0.42 ,大约是 8.03。

Well, it's slow and it's ugly, and I'm sure many people will come up with better, faster and more beautiful solutions, but this will do the trick for you:嗯,它很慢而且很丑,我相信很多人会想出更好、更快、更漂亮的解决方案,但这对你有用:

weakly_exceeds_sum <- function(m, k){
    tmp <- NULL
    for(i in 1:nrow(m)){
        for(j in 1:nrow(m)){
            if(i+j>=k){
            tmp<-c(tmp, m[i,j])
            }
        }
    }
    sum(tmp)
}

where you'd call the function with, for example: weakly_exceeds_sum(m.ex, 2)您可以在其中调用函数,例如: weakly_exceeds_sum(m.ex, 2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM