我正在尝试根据各种规则转换矩阵。
拿这个矩阵,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
,但不确定这与此相关。我也可以将矩阵融入成对列表并做一个冗长的解决方案 - 但这样做的目的是运行数千次模拟,因此速度非常非常重要。
任何指导意见。
答案 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