tidyr::gather与reshape2::melt在矩阵上的区别

12

我长期以来一直在以一种非标准的方式使用reshape2::melt:我运行数字实验并得到一个矩阵作为结果。然后我将其转换为长格式,并生成一些图像。

受到reshape2tidyr之间的相似性的启发,我现在正在尝试在类矩阵的对象上实现完全相同的输出。但目前没有成功:

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

请注意,melt是智能的,如果存在dimnames,它会保留它们。我已经学习了它的工作原理,因此我可以潜在地将以下函数添加到方法分派中:

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

但问题是,我能否强制gather在我的情况下像melt一样运行?是否有任何参数组合可以在matmat2上产生所需的输出结果?


考虑到“tidyr是为与dplyr一起使用而设计的”,而“dplyr”则“专注于处理数据框架的工具”,我认为你最好坚持使用melt(因为gather似乎只是melt的一个包装器)。 - A5C1D2H2I1M1N2O1R2T1
@AnandaMahto 我确实倾向于这样做,只是想知道是否有什么明显的遗漏 :) - tonytonov
1
如果真的需要一个“gather”方法,我猜你可以省去重写的麻烦,直接使用“gather.matrix <- reshape2:::melt.matrix”.... :-) - A5C1D2H2I1M1N2O1R2T1
@AnandaMahto,这很不错,我没想到过 :) 你的这两条评论总结起来是一个不错的答案,你想发表一篇回答吗? - tonytonov
1个回答

12

也许会出现更好的答案,但在此期间,我将把我的评论转换为回答:

引用“tidyr”自述文件中的内容:

请注意,tidyr旨在与dplyr一起使用,因此您应始终同时加载两者。

... 还从“dplyr”的README中:

dplyr是plyr的下一次迭代,专注于处理数据框(因此名称中有 d )的工具。

因此,不为矩阵提供方法“有点”合理。


由于 gather 已经包装了melt,如果你真的想要一个 matrix 方法,你可以节省写一个自定义函数的时间,只需要做类似这样的事情:

gather.matrix <- reshape2:::melt.matrix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接