在R中为矩阵中某些相关性生成图表

12

我希望生成变量(列)之间存在相关性的图表,包括相关性大于和小于某一点且p值小于0.01的变量。这些图表将是使用ggplot2绘制的线形或条形图,绘制两个相关的列(变量)。

目前我的方法概述如下,附有虚拟数据,我希望得到下一步的指引。

# Create some dummy data
df <- data.frame(sample(1:50), sample(1:50), sample(1:50), sample(1:50))
colnames(df) <- c("var1", "var2", "var3", "var4")

# Find correlations in the dummy data
df.cor <- cor(df)

# Make up some random pvalues for this example
x <- 0:1000
df.cor.pvals <- data.frame(sample(x/1000, 4), sample(x/1000, 4), sample(x/1000, 4), sample(x/1000,4))
colnames(df.cor.pvals) <- c("var1", "var2", "var3", "var4")

# Find the significant correlations
df.cor.extreme <- ((df.cor < -0.01 | df.cor > 0.01) & df.cor.pvals < 0.5)

# Ready data to for plotting
df$rownames <- rownames(df)
df.melt <- melt(df, id="rownames")

# I want to plot the combinations of variables that have a TRUE value
# in the df.cor.extreme matrix 

如果var1和var2的值为TRUE,则下面是硬编码示例。我认为这就是需要某种循环来生成多个情节,其中varA和varB相关的地方。

ggplot(df.melt[(df.melt$variable=="var1" | df.melt$variable=="var2"),], aes(x=rownames, y=value, group=variable, colour=variable)) +
  geom_line()

示例图


3
我不理解你的P值数据框 df.cor.pvals 为什么有50行 - 它不应该与 df.cor 相同吗? - Drew Steen
1
你可以使用 df.cor.extreme <- df.cor < -0.01 | df.cor > 0.01 来获取你所需的相关矩阵。 - Drew Steen
修正了我的虚拟数据,并采用单一逻辑运算符结合您的建议。还开始绘制图表,只是无法自动化绘制 df.cor.extreme 矩阵中 TRUE 值的图表。 - themartinmcfly
@themartinmcfly,我还是对你的最终图表感到困惑。当满足某些条件时,您想要绘制原始值。如果cond(v1,v2)没问题,那么绘制什么?绘制v1吗?绘制v1 vs v2吗? - agstudy
@agstudy 我已经添加了一张图表,只是为了可视化。 - themartinmcfly
显示剩余2条评论
2个回答

8

正如评论@DrewSteen所说,p-value必须与cor的形状相同。

在这里,我提供一个计算p值矩阵的函数(在stats包中应该存在内置函数)。

pvalue.matrix <- function(x,...){
  ncx <- ncol(x)
  r <- matrix(0, nrow = ncx, ncol = ncx)
  for (i in seq_len(ncx)) {
    for (j in seq_len(i)) {
      x2 <- x[, i]
      y2 <- x[, j]
      r[i, j] <-  cor.test(x2,y2,...)$p.value
    }
  }
  r <- r + t(r) - diag(diag(r))
  rownames(r) <- colnames(x)
  colnames(r) <- colnames(x)
  r
}

然后您可以像这样使用向量化版本的|和&:
df.cor.sig <- (df.cor > 0.01 | df.cor < -0.01) & pvalue.matrix(df) < 0.5

使用geom_tile绘图的情节经典

library(reshape2) ## melt
library(plyr)     ## round_any
 library(ggplot2) 
dat <- expand.grid(var1=1:4, var2=1:4)
dat$value <- melt(df.cor.sig)$value
dat$labels <- paste(round_any(df.cor,0.01) ,'(', round_any(pvalue.matrix(df),0.01),')',sep='')
ggplot(dat, aes(x=var1,y=var2,label=labels))+ 
  geom_tile(aes(fill = value),colour='white')+
 geom_text()

输入图像说明

在OP澄清后编辑


(未提供需要翻译的内容)
plots <- apply(dat,1,function(x){
    plot.grob <- nullGrob()
    if(length(grep(pattern='TRUE',x[3])) >0 ){
      gg <- paste('var',c(x[1],x[2]),sep='')
      p <- ggplot(subset(df.melt,variable %in% gg ), 
            aes(x=rownames, y=value, group=variable, colour=variable)) +
            geom_line()
      plot.grob <- ggplotGrob(p)
    }
    plot.grob

})


library(gridExtra)
do.call(grid.arrange,  plots)

enter image description here


这非常接近我所寻找的,我将尝试更多地使用expand.grid。我认为如果我能获得像这样的数据框架 变量1,变量2,显著性; 变量1,变量3,假我将拥有一个要绘制相关性的列表,只需要循环或类似操作即可。 - themartinmcfly
1
不错的答案。我不熟悉 'round_any' 函数。因此,我想为其他人补充说明,您似乎正在使用 ggplot2、reshape2 和 plyr 包来创建图表。 - Mark Miller
@agstudy,我正在寻找多个图表,每个图表都显示变量之间的显著相关性。我猜想下一步可能是使用包含这些数据的数据框架。 - themartinmcfly
@agstudy 我已经更改了问题的格式,以便更清楚地编写多个图。我还要感谢您提供的pvalue代码演示,我已经修改了自己的代码,因为它没有使用cor.test,而只是使用了Pearson's。 - themartinmcfly
@agstudy 非常好!比手动计算要好得多 :) - themartinmcfly
显示剩余8条评论

1

如果您自己进行此操作,我想添加一个与 @ agstudy 的答案相关的补充说明。

如果您玩弄生成可以应用重要性的矩阵索引表的函数的结果。即这一行:

dat <- expand.grid(var1=1:4, var2=1:4)

此外,请记住上面一行中硬编码的4是您(正方形)网格的长度。无论如何,您可以通过编写以下代码来忽略任何重复图的生成:
# Find redunant pairs
dat <- data.frame(t(apply(dat, 1, function(x){
  if(x[1]-x[2] <= 0) {    # If > zero than pair has come before.
    -x                    # If = zero than pair is same 
  } else x
})))

# Remove redundant pairs
dat <- dat[dat$var1>0,]

享受吧!


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