расплавить нижнюю половину матрицы в R - PullRequest
15 голосов
/ 22 ноября 2011

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

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  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

Ответы [ 5 ]

17 голосов
/ 22 ноября 2011

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

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

Полагаю, я объясню это немного.Я использую три «хитрости»:

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

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

reshape2::melt(A, varnames = c('row', 'col'), na.rm = TRUE)
1 голос
/ 22 ноября 2011

Вот метод, использующий 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
1 голос
/ 22 ноября 2011

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

# 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 , которая до сих пор, тем не менее,

1 голос
/ 22 ноября 2011

Вот мое первое решение:

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.
...