Schnell das kartesische Produkt aus einer Matrix erzeugen
Frage
Lassen Sie uns sagen, dass ich eine Matrix x
haben, die 10 Zeilen und 2 Spalten enthält. Ich mag eine neue Matrix M
erzeugen, die jedes eindeutiges Paar von Reihen von x
enthält -. Das heißt, eine neue Matrix mit 55 Zeilen und 4 Spalten
z. B.
x <- matrix (nrow=10, ncol=2, 1:20)
M <- data.frame(matrix(ncol=4, nrow=55))
k <- 1
for (i in 1:nrow(x))
for (j in i:nrow(x))
{
M[k,] <- unlist(cbind (x[i,], x[j,]))
k <- k + 1
}
Also, x
ist:
[,1] [,2]
[1,] 1 11
[2,] 2 12
[3,] 3 13
[4,] 4 14
[5,] 5 15
[6,] 6 16
[7,] 7 17
[8,] 8 18
[9,] 9 19
[10,] 10 20
Und dann M
hat vier Säulen, die ersten beiden sind eine Reihe von x
und die nächsten 2 sind eine weitere Reihe von x
:
> head(M,10)
X1 X2 X3 X4
1 1 11 1 11
2 1 11 2 12
3 1 11 3 13
4 1 11 4 14
5 1 11 5 15
6 1 11 6 16
7 1 11 7 17
8 1 11 8 18
9 1 11 9 19
10 1 11 10 20
Gibt es entweder ein schneller oder einfacher (oder beides) Weg, dies in R zu tun?
Lösung
Die expand.grid()
Funktion nützlich für diese:
R> GG <- expand.grid(1:10,1:10)
R> GG <- GG[GG[,1]>=GG[,2],] # trim it to your 55 pairs
R> dim(GG)
[1] 55 2
R> head(GG)
Var1 Var2
1 1 1
2 2 1
3 3 1
4 4 1
5 5 1
6 6 1
R>
Jetzt haben Sie die 'n * (n + 1) / 2' Subsets und Sie können einfache Index Ihrer ursprünglichen Matrix.
Andere Tipps
Ich bin nicht ganz grokking, was Sie tun, damit ich nur etwas wegzuwerfen, das können, oder auch nicht helfen.
Hier ist, was ich mir vorstellen, wie das kartesische Produkt der zwei Spalten:
expand.grid(x[,1],x[,2])
Sie können auch die „Beziehungen“ Paket versuchen. Hier ist die Vignette. Es sollte so arbeiten :
relation_table(x %><% x)
Mit Dirk Antwort:
idx <- expand.grid(1:nrow(x), 1:nrow(x))
idx<-idx[idx[,1] >= idx[,2],]
N <- cbind(x[idx[,2],], x[idx[,1],])
> all(M == N)
[1] TRUE
Danke an alle!
aus den anderen Antworten inspiriert, hier ist eine Funktion kartesisches Produkt zweier Matrizen, im Falle von zwei Matrizen, die Vollkartesisches Produkt, für nur ein Argument der Umsetzung eines von jedem Paar Weglassen:
cartesian_prod <- function(M1, M2) {
if(missing(M2)) { M2 <- M1
ind <- expand.grid(1:NROW(M1), 1:NROW(M2))
ind <- ind[ind[,1] >= ind[,2],] } else {
ind <- expand.grid(1:NROW(M1), 1:NROW(M2))}
rbind(cbind(M1[ind[,1],], M2[ind[,2],]))
}