5

我已经转移到新服务器并在其上安装了 R 版本 3.0。(gplots 库不再适用于 2.14)

使用适用于 2.14 版的脚本,我现在遇到了生成热图的问题。

在 R 版本 3 中,我收到一个错误:

Error in lapply(args, is.character) : node stack overflow
Error in dev.flush() : node stack overflow
Error in par(op) : node stack overflow

在 R 版本 2.14 中,我收到一个错误:

Error: evaluation nested too deeply: infinite recursion / options(expressions=)?

我可以通过增加选项来解决(表达式=500000)

在 R 版本 3 中,增加此选项并不能解决问题。而且我仍然遇到同样的错误。

两者的脚本相同:

y=read.table("test", row.names=1, sep="\t", header=TRUE)
hr <- hclust(dist(as.matrix(y)))
hc <- hclust(dist(as.matrix(t(y))))
mycl <- cutree(hr, k=7); mycolhc <- rainbow(length(unique(mycl)), start=0.1, end=0.9); mycolhc     <- mycolhc[as.vector(mycl)] 

install.packages("gplots")
library("gplots", character.only=TRUE)
myheatcol <- redgreen(75)

pdf("heatmap.pdf")
heatmap.2(as.matrix(y), Rowv=as.dendrogram(hr), Colv=as.dendrogram(hc), col=myheatcol,scale="none", density.info="none", trace="none", RowSideColors=mycolhc, labRow=FALSE)
dev.off()

其中“test”是一个 tdl 文件,带有标题和行名以及一个 40*5000 0/1 矩阵

任何帮助,将不胜感激

PS:当我将数据集减少到 2000 行时,我不再收到错误消息。

PSS:将数据集增加到 2500 行会导致相同的错误;但是,删除所有非信息行(全为 1)给我留下了 3700 行。使用此数据集不会导致错误。

4

3 回答 3

6

我是 gplots 包的作者。当字节编译函数有太多递归调用时,会发生“节点堆栈溢出”错误。

在这种情况下,发生这种情况是因为绘制树状图对象 (stats:::plotNode) 的函数是使用递归算法实现的,并且树状图对象嵌套很深。

最终,正确的解决方案是修改 plotNode 以使用迭代算法,这将防止递归深度错误的发生。

在短期内,可以强制 stats:::plotNode 作为解释代码运行,而不是通过讨厌的 hack 字节编译代码运行。

这是食谱:

## Convert a byte-compiled function to an interpreted-code function 
unByteCode <- function(fun)
    {
        FUN <- eval(parse(text=deparse(fun)))
        environment(FUN) <- environment(fun)
        FUN
    }

## Replace function definition inside of a locked environment **HACK** 
assignEdgewise <- function(name, env, value)
    {
        unlockBinding(name, env=env)
        assign( name, envir=env, value=value)
        lockBinding(name, env=env)
        invisible(value)
    }

## Replace byte-compiled function in a locked environment with an interpreted-code
## function
unByteCodeAssign <- function(fun)
    {
        name <- gsub('^.*::+','', deparse(substitute(fun)))
        FUN <- unByteCode(fun)
        retval <- assignEdgewise(name=name,
                                 env=environment(FUN),
                                 value=FUN
                                 )
        invisible(retval)
    }

## Use the above functions to convert stats:::plotNode to interpreted-code:
unByteCodeAssign(stats:::plotNode)

## Now raise the interpreted code recursion limit (you may need to adjust this,
##  decreasing if it uses to much memory, increasing if you get a recursion depth error ).
options(expressions=5e4)

## heatmap.2 should now work properly 
heatmap.2( ... )
于 2014-09-16T20:04:12.267 回答
4

另一篇文章中,这是 fromstats:::midcache.dendrogram的函数setmidsetmid递归地调用自己,这种递归可能太深了——可能树状图太密集而在视觉上没有任何意义?您可以通过查看错误发生traceback()后的最后几行来了解错误发生的位置。

为了在这方面取得进一步进展,您需要能够提供一个最小的可重现示例(使用heatmap而不是heatmap.2,或者根据您对 traceback() 的解释甚至更细化),可能通过使数据文件可用,或者通过提供配方以可靠地再现错误的方式模拟数据(m <- matrix(runif(1000), 40)?)。

于 2013-05-15T13:31:03.150 回答
3

This problem ("node stack overflow" error while using heatmap.2 function) occurs due to too many identical values in a specific column in your matrix, which causes recursion issue on R producing the error.

What I can suggest (which at least how I solved my very exact problem for my data) is to produce random numbers around the identical numbers and replace them with the original numbers in the matrix:

for (i in 1:nrow(my_matrix)) {
   if (my_matrix[i,my_column]=="100") { # assume i have too many 100 in my_column
      my_matrix[i,my_column]=runif(1,99,101) # replace 100 with nearby values randomly
    }
}

In this way, the heatmap is created without any issue since there are not too many identical numbers anymore, and also it virtually doesn't affect your matrix since you can choose a very small interval for random number generation around your identical value which will still reflect the original values with invisible color changes on the heatmap.

于 2013-12-09T16:39:05.403 回答