在r中转换矩阵的更快捷的方法?

时间:2014-09-20 20:47:46

标签: r matrix

我正在尝试根据各种规则转换矩阵。

拿这个矩阵,m:

x<-c(NA,0,0,0,0,0,4,NA,0,0,1,1,0,0,NA,0,2,4,4,1,3,NA,2,3,0,1,2,0,NA,1,0,0,0,0,0,NA)
m<-matrix(x,6,6, byrow=T)
rownames(m)<-colnames(m)<-LETTERS[1:6]
m

#   A  B  C  D  E  F
#A NA  0  0  0  0  0
#B  4 NA  0  0  1  1
#C  0  0 NA  0  2  4
#D  4  1  3 NA  2  3
#E  0  1  2  0 NA  1
#F  0  0  0  0  0 NA

转换规则如下:

1)对角线应保持NA。

2)对于m [i,j]> m [j,i]的所有实例,则m [i,j]得到'1',m [j,i]得到0。

3)对于m [i,j] == m [j,i]并且两者都不等于0的所有实例,则m [i,j]和m [j,i]都应该被赋值为0.5

4)当m [i,j]和m [j,i]都等于0时,其中一个应该随机得到一个'1'而另一个应该得到一个'0'。

我可以通过此计算执行步骤1-3:

 m1 <- (m > t(m))+0 + (((m == t(m)) & (m!=0 & t(m)!=0)) + 0)/2
 m1

给出:

#   A   B   C  D   E  F
#A NA 0.0 0.0  0 0.0  0
#B  1  NA 0.0  0 0.5  1
#C  0 0.0  NA  0 0.5  1
#D  1 1.0 1.0 NA 1.0  1
#E  0 0.5 0.5  0  NA  1
#F  0 0.0 0.0  0 0.0 NA

现在我需要做第4步。在这个矩阵中m1 [i,j]和m1 [j,i]都等于0的实例可以找到:

(m1==0 & t(m1)==0)

   #       A     B     C     D     E     F
   # A    NA FALSE  TRUE FALSE  TRUE  TRUE
   # B FALSE    NA  TRUE FALSE FALSE FALSE
   # C  TRUE  TRUE    NA FALSE FALSE FALSE
   # D FALSE FALSE FALSE    NA FALSE FALSE
   # E  TRUE FALSE FALSE FALSE    NA FALSE
   # F  TRUE FALSE FALSE FALSE FALSE    NA

表示实例是AC / CA,AE / EA,AF / FA,BC / CB。

我正在寻找的输出示例:

#   A   B   C  D   E  F
#A NA 0.0 1.0  0 0.0  0
#B  1  NA 1.0  0 0.5  1
#C  0 0.0  NA  0 0.5  1
#D  1 1.0 1.0 NA 1.0  1
#E  1 0.5 0.5  0  NA  1
#F  1 0.0 0.0  0 0.0 NA

我知道可以为上三角和下三角分配相同的值,例如此代码中的NA:m1[((m1==0 & t(m1)==0))] <- NA,但不确定这与此相关。我也可以将矩阵融入成对列表并做一个冗长的解决方案 - 但这样做的目的是运行数千次模拟,因此速度非常非常重要。

任何指导意见。

1 个答案:

答案 0 :(得分:7)

也许这比它需要的更复杂,但是它起作用并且它都是矢量化的:

i <- m1==0 & t(m1)==0 & lower.tri(m1)
m1[i] <- sample(0:1, sum(i), replace = TRUE)
m1[t(i)] <- 1 - m1[i][order(row(i)[i], col(i)[i])]

编辑:这是第二种使用矩阵索引的方法,可能稍微复杂一些:

i <- which(m1==0 & t(m1)==0 & lower.tri(m1), TRUE)
z <- sample(0:1, nrow(i), replace = TRUE)
m1[i[, 1:2]] <- z
m1[i[, 2:1]] <- 1 - z