我使用 gplots 中的 heatmap.2 制作热图:
library(gplots)
# some fake data
m = matrix(c(0,1,2,3), nrow=2, ncol=2)
# make heatmap
hm = heatmap.2(m)
当我直接执行“heatmap.2”时,我会得到一个可以输出到设备的图。我怎样才能从我的变量'hm'再次制作情节?显然这是一个玩具示例,在现实生活中,我有一个函数可以生成并返回一个热图,我想稍后再绘制它。
有几种选择,尽管它们都不是特别优雅。这取决于您的函数使用的变量是否在绘图环境中可用。heatmap.2不返回正确的“热图”对象,尽管它包含再次绘制图形的必要信息。查看str(hm)以检查对象。
如果变量在您的环境中可用,您可以重新评估原始绘图调用:
library(gplots)
# some fake data (adjusted a bit)
set.seed(1)
m = matrix(rnorm(100), nrow=10, ncol=10)
# make heatmap
hm = heatmap.2(m, col=rainbow(4))
# Below fails if all variables are not available in the global environment
eval(hm$call)
我认为情况并非如此,因为您提到您正在从函数内部调用 plot 命令,并且我认为您没有使用任何全局变量。您可以从hm对象中可用的字段重新构建热图绘图调用。问题是原始矩阵不可用,而是我们有一个重新组织的$carpet -field。它需要一些修补才能获得原始矩阵,因为投影是:
# hm2$carpet = t(m[hm2$rowInd, hm2$colInd])
至少在数据矩阵没有被缩放的情况下,下面应该可以工作。根据您的特定绘图调用添加额外参数。
func <- function(mat){
h <- heatmap.2(mat, col=rainbow(4))
h
}
# eval(hm2$call) does not work, 'mat' is not available
hm2 <- func(m)
# here hm2$carpet = t(m[hm2$rowInd, hm2$colInd])
# Finding the projection back can be a bit cumbersome:
revRowInd <- match(c(1:length(hm2$rowInd)), hm2$rowInd)
revColInd <- match(c(1:length(hm2$colInd)), hm2$colInd)
heatmap.2(t(hm2$carpet)[revRowInd, revColInd], Rowv=hm2$rowDendrogram, Colv=hm2$colDendrogram, col=hm2$col)
此外,我认为您可以按照自己的方式在函数环境中评估hm$call 。也许with -function 会很有用。
您也可以通过将mat附加到全局环境来使其可用,但我认为这被认为是不好的做法,因为过于急切地使用attach会导致问题。请注意,在我的示例中,每次调用func都会创建原始图。
我会做一些函数式编程:
create_heatmap <- function(...) {
plot_heatmap <- function() heatmap.2(...)
}
data = matrix(rnorm(100), nrow = 10)
show_heatmap <- create_heatmap(x = data)
show_heatmap()
将您需要发送到 plot_heatmap 的所有参数通过...
. 外部函数调用设置了一个环境,在该环境中内部函数首先查找其参数。内部函数作为对象返回,现在是完全可移植的。这应该每次都产生完全相同的情节!