Matrix indices ordered by the value they contain - r

I have a matrix like this:
mat<-matrix(c(10,45,2,15,3,98,1,7,13),nrow = 3)
mat
[,1] [,2] [,3]
[1,] 10 15 1
[2,] 45 3 7
[3,] 2 98 13
I want to get the indices of ordered values, as what we can get from order(x, arr.idx = T) but applied to a matrix. That is:
[,1] [,2]
1 3
3 1
2 2
2 3
1 1
3 3
1 2
2 1
3 2
Is it there a fast way to do it?
Thank you in advance

You can use
arrayInd(order(mat), dim(mat), dimnames(mat))
# [,1] [,2]
# [1,] 1 3
# [2,] 3 1
# [3,] 2 2
# [4,] 2 3
# [5,] 1 1
# [6,] 3 3
# [7,] 1 2
# [8,] 2 1
# [9,] 3 2

Using the order as index, we rearrange the row and col of 'mat' and cbind it to get the row/column index of the ordered values
i1 <- order(mat)
cbind(row(mat)[i1], col(mat)[i1])
# [,1] [,2]
#[1,] 1 3
#[2,] 3 1
#[3,] 2 2
#[4,] 2 3
#[5,] 1 1
#[6,] 3 3
#[7,] 1 2
#[8,] 2 1
#[9,] 3 2

Related

Concatenate each row of a matrix with each element of another matrix R

I want to concatenate each row of a matrix (say m1) with each element of another matrix (m2). Here follows an exmple:
m1 <- t(combn(4,2))
m2 <- matrix(NA,nrow(m1),2)
for(i in 1:nrow(m1)){
m2[i,] <- seq(1,4,1)[-c(m1[i,])]
}
> m1
[,1] [,2]
[1,] 1 2
[2,] 1 3
[3,] 1 4
[4,] 2 3
[5,] 2 4
[6,] 3 4
> m2
[,1] [,2]
[1,] 3 4
[2,] 2 4
[3,] 2 3
[4,] 1 4
[5,] 1 3
[6,] 1 2
The matrix that I want should be like this:
> m3
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 2 4
[3,] 1 3 2
[4,] 1 3 4
[5,] 1 4 2
[6,] 1 4 3
[7,] 2 3 1
[8,] 2 3 4
[9,] 2 4 1
[10,] 2 4 3
[11,] 3 4 1
[12,] 3 4 2
What is the best practice in this case?
As per the expected output, the logic seems to be that we are expanding the rows of the first dataset by also includng the second dataset, so the number of rows should be double as of the first. In the current approach, we used rep to expand the rows and then cbind with the vector created from the second matrix
cbind(m1[rep(1:nrow(m1), each = 2),], c(t(m2)))
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 1 2 4
# [3,] 1 3 2
# [4,] 1 3 4
# [5,] 1 4 2
# [6,] 1 4 3
# [7,] 2 3 1
# [8,] 2 3 4
# [9,] 2 4 1
#[10,] 2 4 3
#[11,] 3 4 1
#[12,] 3 4 2

How to find all the possible permutations of a matrix in R?

I have a matrix, for example, 5x5.
[,1] [,2] [,3] [,4] [,5]
[1,] 22 -2 -2 -2 2
[2,] -2 22 2 2 2
[3,] -2 2 22 2 2
[4,] -2 2 2 22 2
[5,] 2 2 2 2 22.
As you can see, the matrix is symmetric.
Above the main diagonal, there are 4+3+2+1=10 positions, and I find via combn all the possible (permutation) matrices, which have (-2) 3 times in these 10 positions. That means 10!/3!*7!=120 matrices.
But some of them are equivalent.
So,my problem is how to find the non-equivalent matrices from the 120.
I am taking about permutation matrices, because if I pick one of the 120 matrices and I use rmperm, I have as a result one (random) of the 120 matrices.
When I have 5x5 and 6x6 matrices, I don't have problem, because I have developed an algorithm. But now I want to do the same in a 7x7 matrix and more, but the algorithm is very slow, because I have lots of loops.
So, I want with one command, when I pick a matrix from the 120 matrices, to give me ALL the permutations matrices from the 120.
Thanks a lot!
Basically, you're asking for all row/column permutations. For an n x n matrix there are n! (n factorial) permutations of the rows and n! permutations of the columns, for a total of (n!)^2 total row/column permutations (not all of which are necessarily unique).
The first step would be to obtain a sample dataset and get the set of all permutations of the row/column indices (I'm assuming square matrices but it would be easy to extend to the non-square case):
# Sample dataset:
library(sna)
set.seed(100)
(g <- rgraph(3))
# [,1] [,2] [,3]
# [1,] 0 0 1
# [2,] 1 0 0
# [3,] 1 1 0
# All permutations of indices
library(gtools)
(perms <- permutations(nrow(g), nrow(g)))
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 1 3 2
# [3,] 2 1 3
# [4,] 2 3 1
# [5,] 3 1 2
# [6,] 3 2 1
You can compute all pairings of the row/column orderings, which you can use to grab all possible row/column permutations:
pairings <- expand.grid(1:nrow(perms), 1:nrow(perms))
head(pairings)
# Var1 Var2
# 1 1 1
# 2 2 1
# 3 3 1
# 4 4 1
# 5 5 1
# 6 6 1
all.perms <- lapply(1:nrow(pairings), function(x) g[perms[pairings[x,1],], perms[pairings[x,2],]])
head(all.perms)
# [[1]]
# [,1] [,2] [,3]
# [1,] 0 0 1
# [2,] 1 0 0
# [3,] 1 1 0
#
# [[2]]
# [,1] [,2] [,3]
# [1,] 0 0 1
# [2,] 1 1 0
# [3,] 1 0 0
# ...
Finally, you can use unique to grab the elements of all.perms that are unique matrices:
all.unique.perms <- unique(perms)
length(all.unique.perms)
# [1] 18
Basically what you want is permutation of multiset. The package iterpc will do the job.
> library(iterpc)
> I <- iterpc(c(3,7), ordered=TRUE)
> getlength(I)
[1] 120
> getall(I)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 1 1 2 2 2 2 2 2 2
[2,] 1 1 2 1 2 2 2 2 2 2
[3,] 1 1 2 2 1 2 2 2 2 2
[4,] 1 1 2 2 2 1 2 2 2 2
[5,] 1 1 2 2 2 2 1 2 2 2
[6,] 1 1 2 2 2 2 2 1 2 2
[7,] 1 1 2 2 2 2 2 2 1 2
[8,] 1 1 2 2 2 2 2 2 2 1
[9,] 1 2 1 1 2 2 2 2 2 2
[10,] 1 2 1 2 1 2 2 2 2 2
[11,] 1 2 1 2 2 1 2 2 2 2
[12,] 1 2 1 2 2 2 1 2 2 2
[13,] 1 2 1 2 2 2 2 1 2 2
[14,] 1 2 1 2 2 2 2 2 1 2
[15,] 1 2 1 2 2 2 2 2 2 1
[16,] 1 2 2 1 1 2 2 2 2 2
[17,] 1 2 2 1 2 1 2 2 2 2
[18,] 1 2 2 1 2 2 1 2 2 2
[19,] 1 2 2 1 2 2 2 1 2 2
[20,] 1 2 2 1 2 2 2 2 1 2
[ reached getOption("max.print") -- omitted 100 rows ]
Each row here is a permutations of 1 and 2. You should replace the 1's by -2.

Partitioned matrices in R

I’m looking for a code to create matrix B from matrix A, this is a very simple example my real matrix A is (500 x500) and B11(50x50)
1 2 = A
3 4
1 1 | 2 2
1 1 | 2 2
.----------= B
3 3 | 4 4
3 3 | 4 4
Thanks in advance.
You want a Kronecker product, which is %x%:
R>A <- matrix(1:4,2,2)
R>A
[,1] [,2]
[1,] 1 3
[2,] 2 4
R>X <- matrix(1,2,2)
R>X
[,1] [,2]
[1,] 1 1
[2,] 1 1
R>A %x% X
[,1] [,2] [,3] [,4]
[1,] 1 1 3 3
[2,] 1 1 3 3
[3,] 2 2 4 4
[4,] 2 2 4 4
R>t(A) %x% X
[,1] [,2] [,3] [,4]
[1,] 1 1 2 2
[2,] 1 1 2 2
[3,] 3 3 4 4
[4,] 3 3 4 4

R matlab package: why is repmat inconsistent?

I have got a question regarding the matlab package for R. Here's what I get
library(matlab)
a = matrix(1:4,2,2)
repmat(a,3,1)
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 1 2
[4,] 3 4
[5,] 1 2
[6,] 3 4
this is what I expect. replicate a three times along the first dimension. but
b = matrix(1:6,2,3)
b
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
repmat(b,3,1)
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
[4,] 1 2
[5,] 3 4
[6,] 5 6
[7,] 1 2
[8,] 3 4
[9,] 5 6
this is not consistent. I want a 6 by 3 matrix as the one obtained by
rbind(b,rbind(b,b))
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
[3,] 1 3 5
[4,] 2 4 6
[5,] 1 3 5
[6,] 2 4 6
It just appears to be transposing the matrix before doing the stacking. You could just transpose your matrix before sending it into repmat
> repmat(t(b), 3, 1)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
[3,] 1 3 5
[4,] 2 4 6
[5,] 1 3 5
[6,] 2 4 6

how to bind the same vector multiple times?

How can I bind the same vector o = c(1,2,3,4) multiple times to get a matrix like:
o = array(c(1,2,3,4,1,2,3,4,1,2,3,4), dim(c(4,3))
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
[3,] 3 3 3
[4,] 4 4 4
In a nicer way than: o = cbind(o,o,o) and maybe more generalized (duplicate)? I need this to specify colors for elements in textplot.
R recycles. It's very eco-friendly:
o=c(1,2,3,4)
> matrix(o,nrow = 4,ncol = 4)
[,1] [,2] [,3] [,4]
[1,] 1 1 1 1
[2,] 2 2 2 2
[3,] 3 3 3 3
[4,] 4 4 4 4
You can use replicate
> o = c(1,2,3,4)
> replicate(4, o)
[,1] [,2] [,3] [,4]
[1,] 1 1 1 1
[2,] 2 2 2 2
[3,] 3 3 3 3
[4,] 4 4 4 4
You can use outer
outer(1:4,1:4,function(x,y)x)
[,1] [,2] [,3] [,4]
[1,] 1 1 1 1
[2,] 2 2 2 2
[3,] 3 3 3 3
[4,] 4 4 4 4

Resources