我有一个矩阵(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中的循环。如果有人有更有效的方式请分享。
谢谢。
答案 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