如何制作带有大矩阵的热图?
Posted
技术标签:
【中文标题】如何制作带有大矩阵的热图?【英文标题】:How can I make a heatmap with a large matrix? 【发布时间】:2011-08-05 17:50:54 【问题描述】:我有一个 1000*1000 的矩阵(只包含整数 0 和 1),但是当我尝试制作热图时,由于它太大而出现错误。
如何创建具有如此大矩阵的热图?
【问题讨论】:
关于热图的大量答案。 ***.com/questions/3789549/…***.com/questions/5035491/…尝试搜索[r] heatmap
。
请复制并粘贴确切的错误。 1000x1000 不应该产生对 R 来说太大的距离矩阵。
@Roman 但这两个问题都不是……
在对行和列进行任何重新排序后尝试image(m)
?
发布了一个使用heatmap3的解决方案,它更节省内存,尤其是通过它使用fastcluster包进行层次聚类;添加参数 useRaster=TRUE 也有帮助
【参考方案1】:
使用heatmap3
,它比默认的heatmap
函数更节省内存,并且通过使用fastcluster
包来执行层次聚类对我来说更快。添加参数useRaster=TRUE
也有帮助:
library(heatmap3)
nrowcol <- 1000
dat <- matrix(ifelse(runif(nrowcol*nrowcol) > 0.5, 1, 0), nrow=nrowcol)
heatmap3(dat,useRaster=TRUE)
useRaster=TRUE
似乎对于将内存使用保持在限制范围内非常重要。您可以在heatmap.2
中使用相同的参数。计算层次聚类的距离矩阵是计算中的主要开销,但heatmap3
使用更有效的fastcluster
包来处理大型矩阵。 With very large matrices you will unavoidably get into trouble though trying to do a distance-based hierarchical cluster. 在这种情况下,您仍然可以使用参数 Rowv=NA
和 Colv=NA
来抑制行和列树形图,并使用其他一些逻辑来对行和列进行排序,例如
nrowcol <- 5000
dat <- matrix(ifelse(runif(nrowcol*nrowcol) > 0.5, 1, 0), nrow=nrowcol)
heatmap3(dat,useRaster=TRUE,Rowv=NA,Colv=NA)
在我的 8 Gb 内存的笔记本电脑上仍然可以正常运行,而包含树状图的情况下它已经开始崩溃了。
【讨论】:
【参考方案2】:您也可以使用 gplots 包中的 heatmap.2 并简单地关闭树状图,因为这些通常占用最多的计算时间(根据我的经验)。
另外,您是否考虑过通过 pdf()、png() 或 jpeg() 将热图直接打印到文件中?
【讨论】:
【参考方案3】:我可以相信热图至少需要很长时间,因为heatmap
做了很多花哨的东西,需要额外的时间和内存。使用@bill_080 示例中的dat
:
## basic command: 66 seconds
t0 <- system.time(heatmap(dat))
## don't reorder rows & columns: 43 seconds
t1 <- system.time(heatmap(dat,Rowv=NA))
## remove most fancy stuff (from ?heatmap): 14 seconds
t2 <- system.time( heatmap(dat, Rowv = NA, Colv = NA, scale="column",
main = "heatmap(*, NA, NA) ~= image(t(x))"))
## image only: 13 seconds
t3 <- system.time(image(dat))
## image using raster capability in R 2.13.0: 1.2 seconds
t4 <- system.time(image(dat,useRaster=TRUE))
您可能需要考虑您真正想要从热图中得到什么——即,您是否需要花哨的树状图/重新排序的东西?
【讨论】:
【参考方案4】:试试raster包,它可以处理巨大的光栅文件。
【讨论】:
【参考方案5】:我尝试时没有错误。代码如下:
library(lattice)
#Build the data
nrowcol <- 1000
dat <- matrix(ifelse(runif(nrowcol*nrowcol) > 0.5, 1, 0), nrow=nrowcol)
#Build the palette and plot it
pal <- colorRampPalette(c("red", "yellow"), space = "rgb")
levelplot(dat, main="1000 X 1000 Levelplot", xlab="", ylab="", col.regions=pal(4), cuts=3, at=seq(0,1,0.5))
【讨论】:
我能够达到大约 2300X2300 的绘图。 2400X2400 绘图在 levelplot() 语句中给出“使用数据包 1 时出错,无法分配大小为 22.0 Mb 的向量”。 对我来说,这只适用于带有选项 useRaster=TRUE 的较大矩阵,即 levelplot(dat, main="1000 X 1000 Levelplot", xlab="", ylab="", col.regions=朋友(4),切= 3,在=序列(0,1,0.5),用户栅格=真);否则即使使用 5000 x 5000 矩阵,它最终也会分配大约 6 Gb 的内存 - 不好!! 另外,这是一个水平图,而不是包含行和/或列层次聚类的热图,这有很大的不同......【参考方案6】:this SO question 中有关于 R 内存管理的建议。如果您无法分配 1000 x 1000 的图像,那么您可能应该停止尝试在手机上进行统计。
【讨论】:
我可以为我的 palmpilot 反向移植 R 吗? 主要开销不是绘制图像,而是进行层次聚类分析,因为这需要计算成对距离矩阵,众所周知,这很难扩展到更大的问题......甚至仅绘制图像内存使用率异常高 - 5000 x 5000 矩阵的级别图使用 6 Gb 内存;这可以通过在 heatmap.2 或 heatmap3 中使用参数 useRaster=TRUE 来解决....不知道那里的标准热图函数发生了什么...以上是关于如何制作带有大矩阵的热图?的主要内容,如果未能解决你的问题,请参考以下文章
python 如何根据存储在Python列表中的数据制作热图