模拟reshape2 :: melt和pivot_longer矩阵

时间:2020-02-28 10:05:37

标签: r tidyverse tidyr melt

我只是试图在2D矩阵上使用ivot_longer来获取ggplot的“整洁”数据。到目前为止,reshape2::melt

非常简单
library(tidyverse)
library(reshape2)

x <- c(1, 2, 3, 4)
y <- c(1, 2, 3)

Data      <- matrix(round(rnorm(12, 10, 4)), nrow = 4, ncol = 3)
melt_data <- reshape2::melt(Data)

ggplot2::ggplot(meltvec, ggplot2::aes(x = Var1, y = Var2, fill = value)) +
   geom_tile()

但是,pivot_longer需要一个小标题或data.frame。所以我想出了以下功能:

matrix_longer <- function(.data){
  stopifnot(is.matrix(.data),
            !is.data.frame(.data))

  .data <- as.data.frame(.data)
  names(.data) <- 1:ncol(.data)

  .data$Var1 =1:nrow(.data)

   pivot_longer(.data,cols = as.character( 1:(ncol(.data)-1)), names_to = "Var2", values_to = "value") %>% 
     arrange(Var2) %>% 
     mutate(Var2=as.numeric(Var2))
 }

它会产生相同的输出

own_data <- matrix_longer(Data)

ggplot2::ggplot(own_data, ggplot2::aes(x = Var1, y = Var2, fill = value)) +
   geom_tile()

all(own_data==melt_data)

问题是:是否有更好的解决方案?我应该/可以坚持使用reshape2::melt吗?使用.data是个坏主意吗?

1 个答案:

答案 0 :(得分:3)

要从矩阵中获取行和列的索引和值的三列数据框,只需使用as.data.frame.table()

set.seed(9)
Data <- matrix(round(rnorm(12, 10, 4)), nrow = 4, ncol = 3)

as.data.frame.table(Data, responseName = "value")

   Var1 Var2 value
1     A    A    10
2     B    A     9
3     C    A    17
4     D    A     7
5     A    B    10
6     B    B     0
7     C    B    14
8     D    B     7
9     A    C    17
10    B    C    11
11    C    C     9
12    D    C    14

如果您希望索引为整数而不是字母数字值(默认为因子),则可以执行以下操作:

library(dplyr)

as.data.frame.table(Data, responseName = "value") %>%
  mutate_if(is.factor, as.integer)

   Var1 Var2 value
1     1    1    10
2     2    1     9
3     3    1    17
4     4    1     7
5     1    2    10
6     2    2     0
7     3    2    14
8     4    2     7
9     1    3    17
10    2    3    11
11    3    3     9
12    4    3    14