我的问题如下:假设我们有一个二次n * n矩阵,例如
m <- matrix(runif(n^2), n,n)
现在我想定义一个函数f=function(k)
,它返回所有矩阵条目的总和,其行和列的总和弱于k。例如,考虑3 * 3矩阵
m.ex <- matrix(1:9, 3,3, byrow = T)
看起来像
1 2 3
4 5 6
7 8 9
然后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)行和列位置的总和弱超过4 ),(3,1),(3,2)和(3,3))和f(5)= 23 = 6 + 8 + 9(因为行和结肠位置的总和弱位超过5) (2,3),(3,2)和(3,3))。等
答案 0 :(得分:4)
没有循环,希望它有用。
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
用基质熔化的例子:
> 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
答案 1 :(得分:3)
如果我理解正确的话,row
和column
函数会比其他解决方案更简单:
f<-function(k,m)sum(m[row(m) + col(m) >= k])
对于m.ex
:
> sapply(c(2,4,5),f,m=m.ex)
[1] 45 38 23
更大的例子:
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
这可以通过注明您指出的条目是右下角三角形中的条目来确认:
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * 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
所以总和是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。
答案 2 :(得分:2)
嗯,它很慢而且很难看,而且我相信很多人会想出更好,更快,更漂亮的解决方案,但这会为你解决问题:
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)
}
您可以使用,例如:weakly_exceeds_sum(m.ex, 2)