R中的循环和替代方案

时间:2011-07-27 20:31:50

标签: r loops matrix

我有一个矩阵(1051 * 1051),其对角线上有0zeros,其他地方的值大于0zero。目标是有条件地重新分配矩阵中的一些值。例如,我想要实现的标准是:如果任何元素大于400,那么该行/列元素将被赋予0zero值。

这就是我现在的代码设置方式:

dl <- 400       # condition

for( i in 1:dim(DIST)[1] ) {
    for( j in 1:dim(DIST)[1] ) {
        if( DIST[i,j] > dl ) {
             DIS[i,j] <- 0
        }
    }
}

DIST是原始矩阵(1051 * 1051)。

DIS是DIST的副本,需要进行编辑。

我的问题: 有没有其他方法可以做到这一点?更快的方式?

我已经读过应该避免R中的循环。如果有人有更有效的方式请分享。

谢谢。

3 个答案:

答案 0 :(得分:9)

只需使用[]作业:

DIST[DIST>400] <- 0

请参阅?'['了解其工作原理。关键是DIST>400产生长度为length(DIST)的逻辑向量(DIST中的元素数),如果元素> 400则为TRUE,否则为FALSE。然后使用该向量对矩阵进行子集化,并且仅将所选元素分配给。

答案 1 :(得分:6)

尝试

DIS[DIST > d1] <- 0

完整示例:

n <- 10
d1 <- 400
DIST <- matrix(as.integer(runif(n^2)*1e4), n, n)
DIS <- DIST
DIS[DIST > d1] <- 0

答案 2 :(得分:4)

这是一个将矩阵视为向量并使用row()col()函数返回大于条件的条目的相关行和列的示例。

首先,创建一些虚拟数据:

set.seed(1)
m <- matrix(runif(25), ncol = 5)
diag(m) <- 0

接下来,我们使用row()col()返回矩阵中包含每个条目的行或col索引的矩阵。

mr <- row(m)
mc <- col(m)

mr看起来像这样,例如:

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

现在我们设置条件值,并选择那些超出条件的m单元格:

cond <- 0.95
want <- which(m > cond)

如果这些单元格超出条件,我们会为这些单元格提取唯一的行和列索引

rwant <- unique(mr[want])
cwant <- unique(mc[want])

这些是您想要设置为0的行和列。

此处我们将此设置设置为零,首先在m中复制m2进行比较:

m2 <- m
m2[rwant, ] <- 0
m2[, cwant] <- 0

以下是两个矩阵:

> m
          [,1]       [,2]      [,3]      [,4]      [,5]
[1,] 0.0000000 0.89838968 0.2059746 0.4976992 0.9347052
[2,] 0.3721239 0.00000000 0.1765568 0.7176185 0.2121425
[3,] 0.5728534 0.66079779 0.0000000 0.9919061 0.6516738
[4,] 0.9082078 0.62911404 0.3841037 0.0000000 0.1255551
[5,] 0.2016819 0.06178627 0.7698414 0.7774452 0.0000000
> m2
          [,1]       [,2]      [,3] [,4]      [,5]
[1,] 0.0000000 0.89838968 0.2059746    0 0.9347052
[2,] 0.3721239 0.00000000 0.1765568    0 0.2121425
[3,] 0.0000000 0.00000000 0.0000000    0 0.0000000
[4,] 0.9082078 0.62911404 0.3841037    0 0.1255551
[5,] 0.2016819 0.06178627 0.7698414    0 0.0000000