R:如何从不同的数据覆盖热图上的文本?

R: How to overwrite text on heatmap from different data?

有人要求我绘制一个热图,以一种简单的方式显示大量的 p 值。问题是我的老板想用 log(p) 值给图块着色并用 p 值覆盖它们。我设法覆盖了热图上的值(log 或 p),但无法使用来自另一个数据帧的数据来完成。 这些是我的数据(缩短)和代码:

covariate   HbA1c   FPG     Weight  SBP 
Age         0.867   0.928   0.001   0.001   
Sex         0.428   0.565   0.001   0.790   
BMI         0.491   0.435   0.001   0.001   


data <- read.delim(file="hm.txt", sep = "\t")    
df.log <- log(data[,2:12])         #the real data has 12 columns
df.log <- round(df.log, digits=3)

data.cov <- data$covariate
df <- cbind(data.cov,df.log)
df$data.cov = factor(df$data.cov, unique(df$data.cov))

df <- gather(df, key = "factor", value = "pvalue", -data.cov)
df$factor = factor(df$factor, unique(df$factor))

heatmap <- ggplot(df) +
  aes(x = data.cov, y = factor, fill = pvalue, label=pvalue) +
  geom_tile() +
  scale_fill_gradient(low = "#ffffff", high = "#595959",limits=c(-7,0)) + 
  theme_linedraw(base_size = 15) +
  geom_text() +
  theme(text=element_text(family="Roboto"))+
  theme(legend.position = "top", legend.key.width = unit(1.7, "cm"),legend.title=element_blank())+
  theme(axis.text.x=element_text(angle=90,vjust =0.2))
    

这可能只是一个geom_text问题,但我似乎无法成功解决

这可以很容易地实现,方法是首先将数据重塑为长数据,然后添加一个包含日志值的列。这样做你最终会得到一个 df,其中包含一个包含你映射到 fill 的记录 p 值的列和一个包含你映射到 label:

的原始 p 值的列
library(tidyverse)

data <- read.table(text = "covariate   HbA1c   FPG     Weight  SBP 
Age         0.867   0.928   0.001   0.001   
Sex         0.428   0.565   0.001   0.790   
BMI         0.491   0.435   0.001   0.001", header = TRUE)   


df <- gather(data, key = "factor", value = "pvalue", -covariate)
df <- mutate(df, pvalue.log = log(pvalue))
             
ggplot(df) +
  aes(x = covariate, y = factor, fill = pvalue.log, label=pvalue) +
  geom_tile() +
  scale_fill_gradient(low = "#ffffff", high = "#595959",limits=c(-7,0)) + 
  theme_linedraw(base_size = 15) +
  geom_text() +
  #theme(text=element_text(family="Roboto"))+
  theme(legend.position = "top", legend.key.width = unit(1.7, "cm"),legend.title=element_blank())+
  theme(axis.text.x=element_text(angle=90,vjust =0.2))