2

我使用 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'再次制作情节?显然这是一个玩具示例,在现实生活中,我有一个函数可以生成并返回一个热图,我想稍后再绘制它。

4

2 回答 2

5

有几种选择,尽管它们都不是特别优雅。这取决于您的函数使用的变量是否在绘图环境中可用。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都会创建原始图。

于 2013-05-14T11:03:03.373 回答
4

我会做一些函数式编程:

create_heatmap <- function(...) {
    plot_heatmap <- function() heatmap.2(...)
}

data = matrix(rnorm(100), nrow = 10)

show_heatmap <- create_heatmap(x = data)

show_heatmap()

将您需要发送到 plot_heatmap 的所有参数通过.... 外部函数调用设置了一个环境,在该环境中内部函数首先查找其参数。内部函数作为对象返回,现在是完全可移植的。这应该每次都产生完全相同的情节!

于 2013-10-04T22:49:43.313 回答