Search code examples
rsortingmatrixcontingency

Retain column names after permutation of table in R


I have a table in R where the rownames are (as per default) A,B,C,... and the column names are 1,2,3,4,... as assigned. For example, the output of

x <- as.table(matrix(c(2,20,3,4,2,5,8,1,3),nrow=3,ncol=3,byrow=TRUE))
colnames(x) <- seq(1,ncol(x))
x

Now I'd like to permute the table by a matrix P, which I've already found, containing only 1s and 0s (the point being that A %*% P will permute the columns of A so as to maximize its diagonal). In this case, for x you can get P as

P <- matrix(c(0,0,1,1,0,0,0,1,0),nrow=3,byrow=T)

Note P will have only one '1' per row and column, the rest '0'. My issue is: if you do something like

Y <- x %*% P

you will see that, while the diagonals are rightly arranged, the column names from x have been replaced by matrix column names from P ([,1] [,2] [,3] in this case).

How can I perform the permutation (x %*% P) while retaining the column names from x in the correct order? That is to say, the column name follows the column when the column moves. So in this case, the column names would be 2 3 1.


Solution

  • You'll have to permute the column names of x in the same way. For example:

    colnames(Y) <- 1:3 %*% P
    Y
    

    which prints

       2 3 1
    A 20 3 2
    B  2 5 4
    C  1 3 8
    

    This was extra simple because the original column names were integers 1:3. In general, you'll need something like

    colnames(Y) <- colnames(x)[1:3 %*% P]
    

    To check, permute columns of Y:

    Z <- Y %*% P
    colnames(Z) <- colnames(Y)[1:3 %*% P]
    Z
    

    which prints

      3 1  2
    A 3 2 20
    B 5 4  2
    C 3 8  1
    

    Edited to add: As came out in the comments, if P is computed numerically, it might not contain exact 0 and 1 values, so you should use

    colnames(Y) <- colnames(x)[1:3 %*% round(P)]
    

    to avoid rounding error.