Создать матрицу подобия целых чисел, используя R - PullRequest
5 голосов
/ 19 апреля 2011

У меня есть матрица с диагоналями, равными нулю, и недиагональными, равными единице (обратная к единичной матрице):

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

Мне нужна операция, которая будет обобщаться так, чтобы, например, если у меня есть матрица dims 9 на 9 и вектор 0: 8, я смог бы получить эквивалентный результат. Есть идеи как подойти к этому?

Ответы [ 3 ]

6 голосов
/ 19 апреля 2011

Поскольку 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)
6 голосов
/ 19 апреля 2011

В следующем решении используются upper.tri и lower.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 голос
/ 19 апреля 2011

Как насчет:

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-строчным:

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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...