I've been a long time user of reshape2::melt
in a rather non-standard way: I'm running numeric experiments and get a matrix as a result. I then melt it and produce some images.
Inspired by the similarity between reshape2
and tidyr
, I'm now trying to achieve identical output on objects of class matrix. No luck so far:
library(reshape2)
library(tidyr)
set.seed(42)
mat <- matrix(runif(6), 3)
mat2 <- mat
colnames(mat2) <- letters[1:2]
rownames(mat2) <- letters[3:5]
melt(mat)
melt(mat2)
gather(mat) # fails
gather(mat2) # fails
Note that melt
is smart and keeps dimnames
if they are present. I've learnt how it works, so I can potentially add the following function to the method dispatch:
gather.matrix <- function(mat) {
if (is.null(dimnames(mat))) {
grid <- expand.grid(seq.int(nrow(mat)), seq.int(ncol(mat)))
} else {
grid <- expand.grid(dimnames(mat))
}
cbind(grid, value = as.vector(mat))
}
all.equal(melt(mat),
gather.matrix(mat))
#[1] TRUE
all.equal(melt(mat2),
gather.matrix(mat2))
#[1] TRUE
But the question is, can I force gather
act in the same way as melt
in my case? Is there any combination of parameters that would produce the desired output on mat
and mat2
?
Perhaps a better answer will emerge, but in the meantime, I'll convert my comments to an answer:
Quoting from the README to "tidyr":
... and from the README to "dplyr":
As such, it sort of makes sense to not have methods for matrices.
Since
gather
already wraps aroundmelt
, if you really wanted amatrix
method, you can save yourself writing a custom function and just do something like: