Как я могу создать новую матрицу со значениями, отличными от NA, из другой матрицы и строк и столбцов, в которых они были найдены? - PullRequest
1 голос
/ 24 сентября 2019

У меня есть n x n матрица с именем d , которая заполнена в основном значениями NA, но имеет некоторые случайные значения, разбросанные по всему.

Мне нужно создать новую матрицу с именем ds с тремя столбцами с именами head , tail и weight , где weight - это значение, найденное в матрице d , а head и tail - строка и столбец соответственно d где было найдено это конкретное значение для веса .

Матрица d :

n = 1000 
d = runif(n*n) 
d[d < 0.80] = NA 
d = matrix(d,nrow=n,ncol=n) #reshape the vector 
diag(d) = NA # no self-loops 
d[upper.tri(d)] = t(d)[upper.tri(d)] # undirected graphs are symmetric

str(d)
num [1:1000, 1:1000] NA NA NA 0.861 NA ...

Желаемый выход str(ds) и head(ds):

str(ds) 
num [1:99858, 1:3] 1 1 1 1 1 1 1 1 1 1 ... 
- attr(*, "dimnames")=List of 2 
..$ : NULL 
..$ : chr [1:3] "head" "tail" "weight" 

head(ds) 
     head tail    weight 
[1,]    1   15 0.9205357 
[2,]    1   16 0.9938016 
[3,]    1   29 0.9480700

Фактические значения, которые возвращаются вприведенные выше матрицы не важны, потому что они будут генерироваться случайным образом, но мой конечный результат должен выглядеть примерно так.

Что я пробовал:

head = c()
tail = c()
weight = c()
for (i in 1:n)
  for (j in 1:n)
    if (is.na(d[i][j]) == FALSE)
      head[i] = i
      tail[i] = j
      weight[i] = d[i][j]
ds = cbind(head, tail, weight)

Однако это приводит к следующему:

str(ds)
 num [1:1000, 1:3] NA NA 3 NA NA NA NA NA NA NA ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:3] "head" "tail" "weight"

head(ds)
     head tail weight
[1,]   NA   NA     NA
[2,]   NA   NA     NA
[3,]    3   NA     NA
[4,]   NA   NA     NA
[5,]   NA   NA     NA
[6,]   NA   NA     NA

Опять же, как я могу искать по матрице d для значений, отличных от NA, и когда они будут найдены, обновите матрицу ds строкой, в которой она была найдена, столбцом, в котором она была найдена, и самим значением?

1 Ответ

1 голос
/ 24 сентября 2019

Мы можем сделать это чисто с помощью двух хороших трюков R для работы с матрицами: which(arr.ind = TRUE) и индексирование матрицы в [.Ниже я только изменил ваш установочный код, чтобы добавить начальное число для воспроизводимости и сделать n 10, чтобы вы могли видеть все элементы и убедить себя в том, что он делает то, что должен.

Сначала мы используемwhich чтобы вернуть матрицу не-NA индексов строк и столбцов в матрице d.При arr.ind = TRUE мы сохраняем один индекс на измерение входных данных, а не выравниваем вектор перед индексацией.Во-вторых, мы связываем индексы по столбцам с вектором соответствующих весов, полученным путем передачи этой индексной матрицы в [.Вы можете визуально сравнить d и out и увидеть, что значения совпадают.

set.seed(1)
n = 10 
d = runif(n*n) 
d[d < 0.80] = NA 
d = matrix(d,nrow=n,ncol=n) #reshape the vector 
diag(d) = NA # no self-loops 
d[upper.tri(d)] = t(d)[upper.tri(d)]

indices <- which(!is.na(d), arr.ind = TRUE)
out <- cbind(indices, d[indices])
colnames(out) <- c("head", "tail", "weight")
head(out)
#>      head tail    weight
#> [1,]    4    1 0.9082078
#> [2,]    6    1 0.8983897
#> [3,]    7    1 0.9446753
#> [4,]    8    2 0.9919061
#> [5,]    9    3 0.8696908
#> [6,]    1    4 0.9082078

Создано в 2019-09-24 пакетом Представить (v0.3.0)

...