Search code examples
rmatrixr-colnames

Reorder matrix columns based on colnames suffix and the order of a character vector


I have a matrix that looks like this

cols <- c("foo_AFG", "baz_SYR", "baz_TUR", "foo_SYR", "foo_TUR", "baz_AFG")
foo <- matrix(ncol = length(cols))
colnames(foo) <- cols
w <- c("SYR", "AFG", "TUR")

foo

     foo_AFG baz_SYR baz_TUR foo_SYR foo_TUR baz_AFG
[1,]      NA      NA      NA      NA      NA      NA

I would like to reorder the columns of foo so that the suffix of their names resembles the order of w. I only care about the suffixes (all that comes after the "_" separator).

Examples of what I want (and one of what I DON'T want):

# this is OK
     foo_SYR baz_SYR baz_AFG foo_AFG foo_TUR baz_TUR
[1,]      NA      NA      NA      NA      NA      NA

# this is OK
     baz_SYR foo_SYR baz_AFG foo_AFG baz_TUR foo_TUR
[1,]      NA      NA      NA      NA      NA      NA

# this is NOT OK
     foo_SYR foo_AFG foo_TUR baz_SYR baz_AFG baz_TUR
[1,]      NA      NA      NA      NA      NA      NA


Solution

  • You can create an ordered factor only based on the suffix part (extracted with gsub), and use order + [ to arrange the columns.

    ord_fac <- ordered(gsub(".*_", "", colnames(foo)), levels = w)
    foo[, order(ord_fac)]
    
    #   baz_SYR foo_SYR foo_AFG baz_AFG baz_TUR foo_TUR
    # 1      NA      NA      NA      NA      NA      NA