使用'if ... else ...'在所有矩阵元素上对这个双循环嵌套进行矢量化

时间:2017-04-06 07:43:36

标签: r loops for-loop matrix vectorization

我们得到以下R代码,它遍历矩阵A的每一行和每列,如果值为正,则将其保存为矩阵,如果为负,则计算指数值减去1。

qFunc1 <- function(A) {

if (!is.matrix(A) || !is.numeric(A))
    stop("A must be numeric matrix")

B <- matrix(NA, nrow = nrow(A), ncol = ncol(A))

for (i in seq_len(nrow(A)))
{
    for (j in seq_len(ncol(A)))
    {
        if (!is.na(A[i, j]))
        {
            if (A[i, j] > 0)
                B[i, j] <- A[i, j]
            else
                B[i, j] <- exp(A[i, j]) - 1
        }
    }
}

B
}

这段代码给出了正确的结果,但是我们被要求用单线程“向量化”循环嵌套,我不知道如何。另一个“if”中的“if ...... else ......”让我很难过。

提前感谢您的帮助!

请注意,我不允许使用任何*apply函数,因为它们不是“矢量化”。

1 个答案:

答案 0 :(得分:3)

如果没有单线要求我会做

B <- A                        ## initialize the output matrix
ind <- (!is.na(A)) & (A <= 0) ## a logical matrix
B[ind] <- exp(A[ind]) - 1     ## update the output matrix

根据单线要求我会做

B <- ifelse((!is.na(A)) & (A <= 0), exp(A) - 1, A)

这是一个快速测试。

set.seed(0)
A <- round(matrix(rnorm(25), 5, 5), 2)  ## create a 5 x 5 matrix
A[sample.int(length(A), 5)] <- NA       ## set 5 NA
#      [,1]  [,2]  [,3]  [,4]  [,5]
#[1,]  1.26    NA  0.76 -0.41 -0.22
#[2,] -0.33 -0.93    NA  0.25  0.38
#[3,]  1.33 -0.29 -1.15    NA  0.13
#[4,]  1.27 -0.01 -0.29  0.44  0.80
#[5,]  0.41    NA -0.30    NA -0.06

## use your original function
B1 <- qFunc1(A)

## one-liner "vectorization"
B2 <- ifelse((!is.na(A)) & (A <= 0), exp(A) - 1, A)

## check that they give identical results
all.equal(B1, B2)
#[1] TRUE