根据行和列索引在R中高效地填充矩阵

huangapple go评论76阅读模式
英文:

Filling a matrix efficiently in R based on row and column indices

问题

我正在在R中填充一个矩阵,而做这件事最直观的方法是使用两个嵌套的循环:一个用于行,一个用于列。然而,这种方法往往相对较慢,通常更倾向于使用apply()函数。

如果只是用apply来转换矩阵中的现有值,一切都会很容易。但我实际上正在使用一个外部函数,该函数以行和列索引作为参数,并返回一个值。

这个函数可能是这样的(只是一个示例):

myfunction <- function(rownumber, colnumber) {
                       if(rownumber + colnumber < 7) {
                          return(4)
                       } else {
                          return(2)
                       }
}

...使用两个嵌套循环,我们可以这样进行:

m <- matrix(0, nrow = 5, ncol = 5)

for(rownum in 1:nrow(m)) {
    for(colnum in 1:ncol(m)) {
        m[rownum, colnum] <- myfunction(rownum, colnum)
    }
}

结果类似于这样:

> m
     [,1] [,2] [,3] [,4] [,5]
[1,]    4    4    4    4    4
[2,]    4    4    4    4    2
[3,]    4    4    4    2    2
[4,]    4    4    2    2    2
[5,]    4    2    2    2    2

我想要使用apply()函数来实现这一点,因为通常比两个嵌套循环更快,但我不知道如何获得行号和列号,或者是否可能获得它们。一个解决方法是最初将行号和列号保存为字符串到矩阵中,但同样这需要一些时间,因为它需要用两个嵌套的循环来完成... 有什么建议吗?谢谢。

英文:

I am filling a matrix in R, and the most(?) intuitive way to do this is to use two nested loops: one for rows and one for columns. However, this method tends to be quite slow, and the use of apply() function is usually preferable.

Everything would be easy with apply, if I was just transforming the existing values of my matrix with some function, but I am actually using an external function which takes the row and column indices as arguments and returns a value.

The function could be something like this (just an example):

myfunction &lt;- function(rownumber, colnumber) {
                       if(rownumber + colnumber &lt; 7) {
                          return(4)
                       } else {
                          return(2)
                       }
}

...and with two nested loops we could proceed like this:

m &lt;- matrix(0, nrow = 5, ncol = 5)

for(rownum in 1:nrow(m)) {
    for(colnum in 1:ncol(m)) {
        m[rownum, colnum] &lt;- myfunction(rownum, colnum)
    }
}

And something like this comes out:

&gt; m
     [,1] [,2] [,3] [,4] [,5]
[1,]    4    4    4    4    4
[2,]    4    4    4    4    2
[3,]    4    4    4    2    2
[4,]    4    4    2    2    2
[5,]    4    2    2    2    2

I would like to use apply() function for this, since it is generally faster than two nested loops, but I have no idea, how to get row number and column number - or if that's even possible? One solution would be to save the row numbers and col numbers initially to the matrix as STRINGS, but again this would take some time, since it needs to be done with two nested loops...

Any ideas? Thanks.

答案1

得分: 1

If your function is efficiently vectorized, you can do a matrix of row indices and a matrix of column indices as follows:

rownumbers <- matrix(1:4, nrow = 4, ncol = 3)
#      [,1] [,2] [,3]
# [1,]    1    1    1
# [2,]    2    2    2
# [3,]    3    3    3
# [4,]    4    4    4
colnumbers <- t(matrix(1:4, nrow = 4, ncol = 4))[, 1:3]
#      [,1] [,2] [,3]
# [1,]    1    2    3
# [2,]    1    2    3
# [3,]    1    2    3
# [4,]    1    2    3

Then do f(rownumbers, colnumbers).

EDIT

I've just discovered the functions col and row. It's easier to use these functions to construct the two matrices.

英文:

If your function is efficiently vectorized, you can do a matrix of row indices and a matrix of column indices as follows:

rownumbers &lt;- matrix(1:4, nrow = 4, ncol = 3)
#      [,1] [,2] [,3]
# [1,]    1    1    1
# [2,]    2    2    2
# [3,]    3    3    3
# [4,]    4    4    4
colnumbers &lt;- t(matrix(1:4, nrow = 4, ncol = 4))[, 1:3]
#      [,1] [,2] [,3]
# [1,]    1    2    3
# [2,]    1    2    3
# [3,]    1    2    3
# [4,]    1    2    3

Then do f(rownumbers, colnumbers).


EDIT

I've just discovered the functions col and row. It's easier to use these functions to construct the two matrices.

答案2

得分: 1

outer函数应该满足您的需求。

首先,确保您的函数可以进行矢量化处理:

myfunction <- function(rownumber, colnumber) {
     ifelse(rownumber + colnumber < 7, 4, 2) # ifelse是矢量化的
 }

然后使用outer函数:

outer(0:5, 0:5, FUN = myfunction)
英文:

outer should accomplish what you need

First, make sure your function can work vectorized:

myfunction &lt;- function(rownumber, colnumber) {
     ifelse(rownumber + colnumber &lt; 7,4,2) # ifelse is vectorized
 }

Then

outer(0:5, 0:5, FUN = myfunction)

huangapple
  • 本文由 发表于 2023年3月9日 19:57:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75684281.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定