相关矩阵 - tidyr gather v.reshape2 melt

Nic*_*ell 4 r matrix ggplot2 reshape2 tidyr

我想使用ggplot2这样的上三角相关矩阵.我可以很好地复制那个,但由于某种原因,我仍然坚持要将reshape2函数转换为tidyr1.我认为我可以gather代替使用melt,但这不起作用.

原始结果使用 reshape2

library(reshape2)
library(ggplot2)
mydata <- mtcars[, c(1,3,4,5,6,7)]
cormat <- round(cor(mydata),2)
library(reshape2)
melted_cormat <- melt(cormat)

# Get upper triangle of the correlation matrix
get_upper_tri <- function(cormat){
    cormat[lower.tri(cormat)]<- NA
    return(cormat)
}

upper_tri <- get_upper_tri(cormat)

melted_cormat <- melt(upper_tri, na.rm = TRUE)

ggplot(data = melted_cormat, aes(Var2, Var1, fill = value)) + 
    geom_tile()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我尝试使用gather来自tidyr.

library(tidyverse)


#first correlatoin matrix
cor_base <- round(cor(mydata), 2)
#now UT
cor_base[lower.tri(cor_base)] <- NA
cor_tri <- as.data.frame(cor_base) %>% 
    rownames_to_column("Var2") %>% 
    gather(key = Var1, value = value, -Var2, na.rm = TRUE) %>% 
    as.data.frame()

ggplot(data = cor_tri, aes(x = Var2, y = Var1, fill = value)) + 
    geom_tile()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这些值都是相同的,但是发生了一些改变,这使得这看起来不对.检查identical没有返回,TRUE但两个数据框的值似乎相同......

> identical(cor_tri, melted_cormat)
[1] FALSE
> dim(cor_tri)
[1] 21  3
> dim(melted_cormat)
[1] 21  3
> sum(cor_tri == melted_cormat)
[1] 63
Run Code Online (Sandbox Code Playgroud)

对此有任何想法,或者我应该继续加载reshape2以实现我的目标?

谢谢.

Par*_*ait 8

从本质上讲,它是factorcharacter类型VAR1VAR2的reshape2和tidyr版本之间.前者melt()保留因子和相关矩阵的顺序:"mpg", "disp", "hp", "drat", "wt", "qsec"后者tibble:rownames_to_colums()按字母顺序创建字符类型:"disp", "drat", "hp", "mpg", "qsec", "wt".如图所示,两者都有不同的级别影响绘图.

要解决,请考虑使用dplyr::mutate一行,base::factor(rownames(.), ...并明确将这些级别定义为cor_base的原始排列row.names().另外,你的Var1Var2是相反的.

cor_base <- round(cor(mydata), 2)
cor_base[lower.tri(cor_base)] <- NA

cor_tri <- as.data.frame(cor_base) %>% 
  mutate(Var1 = factor(row.names(.), levels=row.names(.))) %>% 
  gather(key = Var2, value = value, -Var1, na.rm = TRUE, factor_key = TRUE) 

ggplot(data = cor_tri, aes(Var2, Var1, fill = value)) + 
  geom_tile()
Run Code Online (Sandbox Code Playgroud)

Cor矩阵绘图输出


此外,对于您或未来的读者,这里的base::reshape版本也会因素水平问题而解决:

cor_base <- round(cor(mydata), 2)
cor_base[lower.tri(cor_base)] <- NA

cor_base_df <- transform(as.data.frame(cor_base),
                         Var1 = factor(row.names(cor_base), levels=row.names(cor_base)))

cor_long <- subset(reshape(cor_base_df, idvar=c("Var1"), 
                           varying = c(1:(ncol(cor_base_df)-1)), v.names="value",
                           timevar = "Var2", 
                           times = factor(row.names(cor_base), levels=row.names(cor_base)),
                           new.row.names = 1:100,
                           direction = "long"), !is.na(value))

ggplot(data = cor_long, aes(Var2, Var1, fill = value)) + 
  geom_tile()
Run Code Online (Sandbox Code Playgroud)