rtidyrreshape2melt

Alternatives to reshape2::melt() for matrices with named rows/columns?


The melt() function from the reshape2 package has a convenient behavior where it will convert a matrix with named rows/columns into a three-column data frame with the matrix row/column names becoming the first two columns:

testmat <- matrix(1:25,nrow=5,dimnames=list(LETTERS[6:10],LETTERS[1:5]))
#   A  B  C  D  E
# F 1  6 11 16 21
# G 2  7 12 17 22
# H 3  8 13 18 23
# I 4  9 14 19 24
# J 5 10 15 20 25

longmat <- reshape2::melt(testmat)
head(longmat)
# Var1 Var2 value
#    F    A     1
#    G    A     2
#    H    A     3
#    I    A     4
#    J    A     5
#    F    B     6

But it has the annoying behavior of making Var1 and Var2 factors, and it does not support a stringsAsFactors=F option. The README for reshape2 says "reshape2 is retired: only changes necessary to keep it on CRAN will be made. We recommend using tidyr instead.", so it seems unlikely this behavior will ever be changed in melt().

I have experimented with alternatives, but haven't found something that works yet:

Main question: Is there some other function (tidyverse or non-tidyverse) that will convert a matrix to long form in a manner similar to reshape2::melt()?

Second question: I've been experimenting with writing my own. Are there any hidden "gotchas" I haven't thought of that might make the function below produce unexpected/incorrect behaviors?

melt_by_hand <- function(mat) {
  return(data.frame(row=rep(rownames(mat),ncol(mat)),
                      col=rep(colnames(mat),each=nrow(mat)),
                      value=as.vector(mat)))
}

Solution

  • Nothing else but as.data.frame.table from base R should help

    > as.data.frame.table(testmat, stringsAsFactors = FALSE)
       Var1 Var2 Freq
    1     F    A    1
    2     G    A    2
    3     H    A    3
    4     I    A    4
    5     J    A    5
    6     F    B    6
    7     G    B    7
    8     H    B    8
    9     I    B    9
    10    J    B   10
    11    F    C   11
    12    G    C   12
    13    H    C   13
    14    I    C   14
    15    J    C   15
    16    F    D   16
    17    G    D   17
    18    H    D   18
    19    I    D   19
    20    J    D   20
    21    F    E   21
    22    G    E   22
    23    H    E   23
    24    I    E   24
    25    J    E   25