2016-12-07 8 views
2

Angenommen, ich habe eine Matrix wie folgt aussieht, die Werte nach oben oder unten auf der Diagonalen sind die gleichen. Mit anderen Worten, [, 1] x [2,] und [, 2] x [1,] sind beide 2 in der Matrix.Konvertieren Sie eine Matrix in Spalten

> 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 

Dann habe ich richtigen Namen für 1, 2 und 3 auch.

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

Wenn ich die Matrix 3 Spalten konvertieren möchte Name für jedes Paar enthält, entspricht, und das Paar muss eindeutig sein, A x B ist die gleiche wie B x A, so halten wir A x B nur. Wie kann ich es mit R erreichen?

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

Antwort

3

Das folgende ist einfach:

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 

Oder Sie es in einer einzigen Zeile tun können: melt(replace(m, lower.tri(m), NA), na.rm = TRUE)

0

Dies wird auch funktionieren:

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