我想知道如何为矩阵相关热图添加另一层重要且需要的复杂性,例如除了R2值(-1到1)之外,显着性水平星的方式之后的p值?br />
在这个问题中没有意图将显着性水平星或p值作为文本放在矩阵BUT的每个方格上,而不是在矩阵的每个方格上的显着性水平的图形开箱即用表示中。我认为只有那些享受创新思维祝福的人才能赢得掌声,解开这种解决方案,以便有最好的方式来代表我们的“半真半导体相关热图”中复杂的复杂成分。我google了很多但从未见过正确或我会说“眼睛友好”的方式来表示显着性水平加上反映R系数的标准色调。
可重现的数据集可在此处找到:
http://learnr.wordpress.com/2010/01/26/ggplot2-quick-heatmap-plotting/
R代码请在下面找到:
library(ggplot2)
library(plyr) # might be not needed here anyway it is a must-have package I think in R
library(reshape2) # to "melt" your dataset
library (scales) # it has a "rescale" function which is needed in heatmaps
library(RColorBrewer) # for convenience of heatmap colors, it reflects your mood sometimes
nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")
nba <- as.data.frame(cor(nba[2:ncol(nba)])) # convert the matrix correlations to a dataframe
nba.m <- data.frame(row=rownames(nba),nba) # create a column called "row"
rownames(nba) <- NULL #get rid of row names
nba <- melt(nba)
nba.m$value<-cut(nba.m$value,breaks=c(-1,-0.75,-0.5,-0.25,0,0.25,0.5,0.75,1),include.lowest=TRUE,label=c("(-0.75,-1)","(-0.5,-0.75)","(-0.25,-0.5)","(0,-0.25)","(0,0.25)","(0.25,0.5)","(0.5,0.75)","(0.75,1)")) # this can be customized to put the correlations in categories using the "cut" function with appropriate labels to show them in the legend, this column now would be discrete and not continuous
nba.m$row <- factor(nba.m$row, levels=rev(unique(as.character(nba.m$variable)))) # reorder the "row" column which would be used as the x axis in the plot after converting it to a factor and ordered now
#now plotting
ggplot(nba.m, aes(row, variable)) +
geom_tile(aes(fill=value),colour="black") +
scale_fill_brewer(palette = "RdYlGn",name="Correlation") # here comes the RColorBrewer package, now if you ask me why did you choose this palette colour I would say look at your battery charge indicator of your mobile for example your shaver, won't be red when gets low? and back to green when charged? This was the inspiration to choose this colour set.
矩阵相关热图应如下所示:
提高解决方案的提示和想法:
- 此代码可能有助于了解从本网站获取的重要级别明星:
http://ohiodata.blogspot.de/2012/06/correlation-tables-in-r-flagged-with.html
R代码:
mystars <- ifelse(p < .001, "***", ifelse(p < .01, "** ", ifelse(p < .05, "* ", " "))) # so 4 categories
- 显着性水平可以作为颜色强度添加到每个方格,如阿尔法美学,但我不认为这将很容易解释和捕获
- 另一个想法是有4个不同大小的正方形对应星星,当然给出最小的非重要性,如果最高的星星增加到全尺寸正方形
- 另一个想法是在这些重要的正方形中包含一个圆圈,并且圆的线条的粗细对应于重要性级别(其余3个类别)所有这些都是一种颜色的颜色
- 与上述相同但固定线条粗细,同时为3个剩余的重要级别提供3种颜色
- 你可能想出更好的想法,谁知道?
答案 0 :(得分:28)
这只是为了提升最终解决方案的尝试,我在这里绘制了星星作为解决方案的指标,但正如我所说,目标是找到一个比星星更好的图形解决方案。我只是使用geom_point和alpha来表示显着性水平,但是NA(包括非重要值)的问题将显示为三星级重要性的问题,如何解决这个问题?我认为使用一种颜色在使用多种颜色时可能会更加眼睛友好,并避免给情节加重许多细节以便眼睛解决。提前谢谢。
这是我第一次尝试的情节:
或者可能这样更好?!
我认为现在最好的是下面的那个,直到你想出更好的东西!
根据要求,以下代码适用于最后一张热图:
# Function to get the probability into a whole matrix not half, here is Spearman you can change it to Kendall or Pearson
cor.prob.all <- function (X, dfr = nrow(X) - 2) {
R <- cor(X, use="pairwise.complete.obs",method="spearman")
r2 <- R^2
Fstat <- r2 * dfr/(1 - r2)
R<- 1 - pf(Fstat, 1, dfr)
R[row(R) == col(R)] <- NA
R
}
# Change matrices to dataframes
nbar<- as.data.frame(cor(nba[2:ncol(nba)]),method="spearman") # to a dataframe for r^2
nbap<- as.data.frame(cor.prob.all(nba[2:ncol(nba)])) # to a dataframe for p values
# Reset rownames
nbar <- data.frame(row=rownames(nbar),nbar) # create a column called "row"
rownames(nbar) <- NULL
nbap <- data.frame(row=rownames(nbap),nbap) # create a column called "row"
rownames(nbap) <- NULL
# Melt
nbar.m <- melt(nbar)
nbap.m <- melt(nbap)
# Classify (you can classify differently for nbar and for nbap also)
nbar.m$value2<-cut(nbar.m$value,breaks=c(-1,-0.75,-0.5,-0.25,0,0.25,0.5,0.75,1),include.lowest=TRUE, label=c("(-0.75,-1)","(-0.5,-0.75)","(-0.25,-0.5)","(0,-0.25)","(0,0.25)","(0.25,0.5)","(0.5,0.75)","(0.75,1)")) # the label for the legend
nbap.m$value2<-cut(nbap.m$value,breaks=c(-Inf, 0.001, 0.01, 0.05),label=c("***", "** ", "* "))
nbar.m<-cbind.data.frame(nbar.m,nbap.m$value,nbap.m$value2) # adding the p value and its cut to the first dataset of R coefficients
names(nbar.m)[5]<-paste("valuep") # change the column names of the dataframe
names(nbar.m)[6]<-paste("signif.")
nbar.m$row <- factor(nbar.m$row, levels=rev(unique(as.character(nbar.m$variable)))) # reorder the variable factor
# Plotting the matrix correlation heatmap
# Set options for a blank panel
po.nopanel <-list(opts(panel.background=theme_blank(),panel.grid.minor=theme_blank(),panel.grid.major=theme_blank()))
pa<-ggplot(nbar.m, aes(row, variable)) +
geom_tile(aes(fill=value2),colour="white") +
scale_fill_brewer(palette = "RdYlGn",name="Correlation")+ # RColorBrewer package
opts(axis.text.x=theme_text(angle=-90))+
po.nopanel
pa # check the first plot
# Adding the significance level stars using geom_text
pp<- pa +
geom_text(aes(label=signif.),size=2,na.rm=TRUE) # you can play with the size
# Workaround for the alpha aesthetics if it is good to represent significance level, the same workaround can be applied for size aesthetics in ggplot2 as well. Applying the alpha aesthetics to show significance is a little bit problematic, because we want the alpha to be low while the p value is high, and vice verse which can't be done without a workaround
nbar.m$signif.<-rescale(as.numeric(nbar.m$signif.),to=c(0.1,0.9)) # I tried to use to=c(0.1,0.9) argument as you might expect, but to avoid problems with the next step of reciprocal values when dividing over one, this is needed for the alpha aesthetics as a workaround
nbar.m$signif.<-as.factor(0.09/nbar.m$signif.) # the alpha now behaves as wanted except for the NAs values stil show as if with three stars level, how to fix that?
# Adding the alpha aesthetics in geom_point in a shape of squares (you can improve here)
pp<- pa +
geom_point(data=nbar.m,aes(alpha=signif.),shape=22,size=5,colour="darkgreen",na.rm=TRUE,legend=FALSE) # you can remove this step, the result of this step is seen in one of the layers in the above green heatmap, the shape used is 22 which is again a square but the size you can play with it accordingly
我希望这可以向前迈进一步!请注意:
- 有人建议对R ^ 2进行不同的分类或切割,好吧我们当然可以做到这一点但我们仍然希望向观众展示显着性水平,而不是用明星级别来扰乱眼睛。我们原则上是否可以实现这一点?
- 有人建议用不同的方法来削减p值,好吧这可以是在没有显示3级重要性而不会使眼睛麻烦的情况下的选择。那么显示没有水平的显着/不显着可能更好
- 对于alpha和size美学,你可能会更好地想出ggplot2中的上述解决方法,希望很快收到你的来信!
- 问题尚未得到解答,等待创新的解决方案!
- 有趣的是,“corrplot”包就可以了!我通过这个包得出了下面的图,PS:交叉的正方形不重要,signif = 0.05。但是我们怎么能把这个翻译成ggplot2,我们可以吗?!
- 或者你可以做圈子并隐藏那些不重要的圈子?如何在ggplot2中执行此操作?!
答案 1 :(得分:1)
为了表示估计相关系数的显着性,您可以改变着色量 - 使用alpha
或仅填充每个图块的子集:
# install.packages("fdrtool")
# install.packages("data.table")
library(ggplot2)
library(data.table)
#download dataset
nba <- as.matrix(read.csv("http://datasets.flowingdata.com/ppg2008.csv")[-1])
m <- ncol(nba)
# compute corellation and p.values for all combinations of columns
dt <- CJ(i=seq_len(m), j=seq_len(m))[i<j]
dt[, c("p.value"):=(cor.test(nba[,i],nba[,j])$p.value), by=.(i,j)]
dt[, c("corr"):=(cor(nba[,i],nba[,j])), by=.(i,j)]
# estimate local false discovery rate
dt[,lfdr:=fdrtool::fdrtool(p.value, statistic="pvalue")$lfdr]
dt <- rbind(dt, setnames(copy(dt),c("i","j"),c("j","i")), data.table(i=seq_len(m),j=seq_len(m), corr=1, p.value=0, lfdr=0))
#use alpha
ggplot(dt, aes(x=i,y=j, fill=corr, alpha=1-lfdr)) +
geom_tile()+
scale_fill_distiller(palette = "RdYlGn", direction=1, limits=c(-1,1),name="Correlation") +
scale_x_continuous("variable", breaks = seq_len(m), labels = colnames(nba)) +
scale_y_continuous("variable", breaks = seq_len(m), labels = colnames(nba), trans="reverse") +
coord_fixed() +
theme(axis.text.x=element_text(angle=90, vjust=0.5),
panel.background=element_blank(),
panel.grid.minor=element_blank(),
panel.grid.major=element_blank(),
)
#use area
ggplot(dt, aes(x=i,y=j, fill=corr, height=sqrt(1-lfdr), width=sqrt(1-lfdr))) +
geom_tile()+
scale_fill_distiller(palette = "RdYlGn", direction=1, limits=c(-1,1),name="Correlation") +
scale_color_distiller(palette = "RdYlGn", direction=1, limits=c(-1,1),name="Correlation") +
scale_x_continuous("variable", breaks = seq_len(m), labels = colnames(nba)) +
scale_y_continuous("variable", breaks = seq_len(m), labels = colnames(nba), trans="reverse") +
coord_fixed() +
theme(axis.text.x=element_text(angle=90, vjust=0.5),
panel.background=element_blank(),
panel.grid.minor=element_blank(),
panel.grid.major=element_blank(),
)
这里的关键是p.values的缩放:为了获得仅在相关区域中显示大变化的易于理解的值,我使用由{提供的本地错误发现(lfdr)的上限估计。 {1}}而是。 即,瓦片的阿尔法值可能小于或等于该相关性与0不同的概率。
答案 2 :(得分:1)
library("corrplot")
nba <- as.matrix(read.csv("https://raw.githubusercontent.com/Shicheng-Guo/Shicheng-Guo.Github.io/master/data/ppg2008.csv")[-1])
res1 <- cor.mtest(nba, conf.level = .95)
par(mfrow=c(2,2))
# correlation and P-value
corrplot(cor(nba), p.mat = res1$p, insig = "label_sig",sig.level = c(.001, .01, .05), pch.cex = 0.8, pch.col = "white",tl.cex=0.8)
# correlation and hclust
corrplot(cor(nba), method = "shade", outline = T, addgrid.col = "darkgray", order="hclust",
mar = c(4,0,4,0), addrect = 4, rect.col = "black", rect.lwd = 5,cl.pos = "b", tl.col = "indianred4",
tl.cex = 0.8, cl.cex = 0.8)