2016-12-07 3 views
2

Предполагая, что у меня есть матрица, как показано ниже, значения вверх или вниз по диагонали одинаковы. Другими словами, [, 1] x [2,] и [, 2] x [1,] оба равны 2 в матрице.Преобразование матрицы в столбцы

> m = cbind(c(1,2,3),c(2,4,5),c(3,5,6)) 
> m 
    [,1] [,2] [,3] 
[1,] 1 2 3 
[2,] 2 4 5 
[3,] 3 5 6 

Тогда у меня есть настоящее имя для 1, 2 и 3.

>Real_name 
A B C # A represents 1, B represents 2, and C represents 3. 

Если я хотел бы преобразовать матрицу в 3-х столбцы, содержащих соответствующую реальное имя для каждой пары, и пара должна быть уникальной, А х В таком же, как В й А, так мы храним А х В только. Как я могу достичь этого, используя R?

A A 1 
A B 2 
A C 3 
B B 4 
B C 5 
C C 6 

ответ

3

Следующая проста:

m <- cbind(c(1,2,3), c(2,4,5), c(3,5,6)) 
## read `?lower.tri` and try `v <- lower.tri(m, diag = TRUE)` to see what `v` is 
## read `?which` and try `which(v, arr.ind = TRUE)` to see what it gives 
ij <- which(lower.tri(m, diag = TRUE), arr.ind = TRUE) 

Real_name <- LETTERS[1:3] 
data.frame(row = Real_name[ij[, 1]], col = Real_name[ij[, 2]], val = c(m[ij])) 

# row col val 
#1 A A 1 
#2 B A 2 
#3 C A 3 
#4 B B 4 
#5 C B 5 
#6 C C 6 
3
colnames(m) <- c("A", "B", "C") 
rownames(m) <- c("A", "B", "C") 

m[lower.tri(m)] = NA     # replace lower triangular elements with NA 
data.table::melt(m, na.rm = TRUE)  # melt and remove NA 

# Var1 Var2 value 
#1 A A  1 
#4 A B  2 
#5 B B  4 
#7 A C  3 
#8 B C  5 
#9 C C  6 

Или вы можете сделать это в одной строке: melt(replace(m, lower.tri(m), NA), na.rm = TRUE)

0

Это также будет работать:

g <- expand.grid(1:ncol(m), 1:ncol(m)) 
g <- g[g[,2]>=g[,1],] 
cbind.data.frame(sapply(g, function(x) Real_name[x]), Val=m[as.matrix(g)]) 

    Var1 Var2 Val 
1 A A 1 
2 A B 2 
3 B B 4 
4 A C 3 
5 B C 5 
6 C C 6 
Смежные вопросы