使用R创建整数的相似性矩阵

时间:2011-04-19 14:55:34

标签: r matrix

我有一个对角线等于零的矩阵,非对角线都等于1(单位矩阵的倒数):

mat1 <- matrix(c(0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0), 5, 5)

我的矢量总是与矩阵的调整长度相同,并始终从零开始:

vec1 <- c(0,1,2,3,4)

使用这两个对象我想创建一个如下所示的矩阵:

mat2 <- matrix(c(0,1,2,3,4,1,0,1,2,3,2,1,0,1,2,3,2,1,0,1,4,3,2,1,0), 5, 5)

     [,1] [,2] [,3] [,4] [,5]
[1,]    0    1    2    3    4
[2,]    1    0    1    2    3
[3,]    2    1    0    1    2
[4,]    3    2    1    0    1
[5,]    4    3    2    1    0

我想要一个可以推广的操作,这样如果我有一个9到9的调光矩阵,和0:8的矢量,我可以得到相同的结果。关于如何处理这个的任何想法?

3 个答案:

答案 0 :(得分:6)

以下解决方案利用upper.trilower.tri来隔离上下三角矩阵。此外,它使用sequence来创建所需的矢量序列。

n <- 9
vec <- (1:n)-1
m <- matrix(0, n, n)
m[lower.tri(m, diag=TRUE)] <- vec[sequence(n:1)]  #### Edit
m <- t(m)
m[lower.tri(m, diag=TRUE)] <- vec[sequence(n:1)]  #### Edit
m

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
 [1,]    0    1    2    3    4    5    6    7    8
 [2,]    1    0    1    2    3    4    5    6    7
 [3,]    2    1    0    1    2    3    4    5    6
 [4,]    3    2    1    0    1    2    3    4    5
 [5,]    4    3    2    1    0    1    2    3    4
 [6,]    5    4    3    2    1    0    1    2    3
 [7,]    6    5    4    3    2    1    0    1    2
 [8,]    7    6    5    4    3    2    1    0    1
 [9,]    8    7    6    5    4    3    2    1    0

答案 1 :(得分:6)

当vec1以零开头时,你可以这样做:

MakeMatrix <- function(x){
  n <- length(x)
  id <- abs(rep(1:n,n)-rep(1:n,each=n)) + 1
  matrix(x[id],ncol=n)
}

MakeMatrix(vec1)

所以没有必要在输入中使用mat1,因为那个实际上是多余的。你可以在函数中构造矩阵。

诀窍在于提供一系列id值来从向量中进行选择,然后将所有内容转换为矩阵。


编辑:如果你只是要使用序列,你也可以这样做:

MakeMatrix <- function(n){
  id <- abs(rep(1:n,n)-rep(1:n,each=n))
  matrix(id,ncol=n)
}

MakeMatrix(7)

答案 2 :(得分:1)

怎么样:

genMat <- function(n){
  mat <- outer(1:n,1:n,"-")%%n
  tmp <- mat[lower.tri(mat)]
  mat <- t(mat)
  mat[lower.tri(mat)] <- tmp
  mat
}

> genMat(5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    1    2    3    4
[2,]    1    0    1    2    3
[3,]    2    1    0    1    2
[4,]    3    2    1    0    1
[5,]    4    3    2    1    0

修改

对于任意vec1

genMat2 <- function(vec){
  n <- length(vec)
  mat <- outer(1:n,1:n,"-")%%n
  tmp <- mat[lower.tri(mat)]
  mat <- t(mat)
  mat[lower.tri(mat)] <- tmp
  matrix(vec[mat+1],n,n)
}

> genMat2(c(0,2,4,3,9))
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    2    4    3    9
[2,]    2    0    2    4    3
[3,]    4    2    0    2    4
[4,]    3    4    2    0    2
[5,]    9    3    4    2    0

编辑2 事实上,没有必要使用模数,然后使用矩阵,abs将正常工作,使原始矩阵定义成为1-liner:

abs(outer(1:n,1:n,"-"))

所以,

genMat <- function(n){
  abs(outer(1:n,1:n,"-"))
}

genMat2 <- function(vec){
  n <- length(vec)
  matrix(vec[abs(outer(1:n,1:n,"-"))+1],n,n)
}