Расплавить матрицу нижней половины в R

Как я могу расплавить нижний полуугольник плюс диагональную матрицу?

11 NA NA  NA  NA
12 22 NA  NA  NA
13 23 33  NA  NA
14 24 34  44  NA
15 25 35  45  55
    A <- t(matrix (c(11,  NA, NA,  NA,  NA, 12, 22, NA,  NA,  NA,
   13, 23, 33,  NA,  NA, 14, 24, 34,  44,  NA,15, 25, 
   35,  45,  55), ncol = 5)) 

 > A
     [,1] [,2] [,3] [,4] [,5]
[1,]   11   NA   NA   NA   NA
[2,]   12   22   NA   NA   NA
[3,]   13   23   33   NA   NA
[4,]   14   24   34   44   NA
[5,]   15   25   35   45   55 

В data.frame в строке и col (сохраняя следующий порядок)

col  row   value 
1     1      11
1     2      12
1     3      13
1     4      14
1     5      15
2     2      22
2     3      23
2     4      24
2     5      25
3     3      33
3     4      34
3     5      35
4     4      44
4     5      45
5     5      55

Ответ 1

Если вы хотите также индексы как столбцы, это должно работать:

m <- matrix(1:25,5,5)
m[upper.tri(m)] <- NA
m

     [,1] [,2] [,3] [,4] [,5]
[1,]    1   NA   NA   NA   NA
[2,]    2    7   NA   NA   NA
[3,]    3    8   13   NA   NA
[4,]    4    9   14   19   NA
[5,]    5   10   15   20   25

cbind(which(!is.na(m),arr.ind = TRUE),na.omit(as.vector(m)))
      row col   
 [1,]   1   1  1
 [2,]   2   1  2
 [3,]   3   1  3
 [4,]   4   1  4
 [5,]   5   1  5
 [6,]   2   2  7
 [7,]   3   2  8
 [8,]   4   2  9
 [9,]   5   2 10
[10,]   3   3 13
[11,]   4   3 14
[12,]   5   3 15
[13,]   4   4 19
[14,]   5   4 20
[15,]   5   5 25

Думаю, я немного объясню это. Я использую три "трюка":

  • Аргумент arr.ind для which для получения индексов
  • Очень полезная функция na.omit, чтобы избежать лишнего ввода текста
  • Тот факт, что R хранит матрицы в основной форме столбца, поэтому as.vector возвращает значения в правильном порядке.

Ответ 2

Мой один лайнер.

reshape2::melt(A, varnames = c('row', 'col'), na.rm = TRUE)

Ответ 3

Здесь мое первое решение:

test <- rbind(c(11,NA,NA,NA,NA),
  c(12,22,NA,NA,NA),
  c(13,23,33,NA,NA),
  c(14,24,34,44,NA),
  c(15,25,35,45,55))  ## Load the matrix

test2 <- as.vector(test)  ## "melt" it into a vector

test <- cbind( test2[!is.na(test2)] )  ## get rid of NAs, cbind it into a column 

Результаты:

> test
      [,1]
 [1,]   11
 [2,]   12
 [3,]   13
 [4,]   14
 [5,]   15
 [6,]   22
 [7,]   23
 [8,]   24
 [9,]   25
[10,]   33
[11,]   34
[12,]   35
[13,]   44
[14,]   45
[15,]   55

В качестве альтернативы вы можете использовать матричную команду:

test <- rbind(c(11,NA,NA,NA,NA),
  c(12,22,NA,NA,NA),
  c(13,23,33,NA,NA),
  c(14,24,34,44,NA),
  c(15,25,35,45,55))  ## Load the matrix

test2 <- matrix(test, ncol=1)  
test <- cbind( test2[!is.na(test2), ] )   
  ## same as above, except now explicitly noting rows to replace.

Ответ 4

Вот моя попытка:

# enter the data
df <- c(11,12,13,14,15,NA,22,23,24,25,NA,NA,33,34,35,NA,NA,NA,44,45,NA,NA,NA,NA,55)
dim(df) <- c(5,5)
df

# make new data frame with rows and column indicators
melteddf <- data.frame(
value=df[lower.tri(df,diag=T)],
col=rep(1:ncol(df),ncol(df):1),
row=unlist(sapply(1:nrow(df),function(x) x:nrow(df)))
)

Мне жаль, что я не знал о части arr.ind cbind, которая до этого теперь.

Ответ 5

Вот метод, использующий arrayInd, который в основном такой же, как @joran, но может быть полезен в других настройках:

na.omit( data.frame(arrayInd(1:prod(dim(A)), dim(A)), value=c(A)) )
   X1 X2 value
1   1  1    11
2   2  1    12
3   3  1    13
4   4  1    14
5   5  1    15
7   2  2    22
8   3  2    23
9   4  2    24
10  5  2    25
13  3  3    33
14  4  3    34
15  5  3    35
19  4  4    44
20  5  4    45
25  5  5    55