【问题标题】:creating a heatmap where the data has NaN values in it创建一个热图,其中数据中包含 NaN 值
【发布时间】:2013-12-31 15:11:37
【问题描述】:

我正在尝试使用 heatmap.2 包创建热图。我的数据中有很多 NaN 值,我想做的是以下内容。每次有 NaN 值时,只需将单元格着色为浅灰色(或其他一些中性色,可能是白色),所有其他值(它们是 log2 表达式)具有标准的绿色/黄色/红色配色方案。这是我一直在使用的代码:

heatmap.2(as.matrix(foo2[rowSums (abs(foo2)) != 0,]),
          col = redgreen,
          margins = c(12, 22),
          trace = "none", 
          xlab = "Comparison",
          lhei = c(2, 8),
          scale = c("none"),
          symbreaks = min(foo2 = 0, na.rm = TRUE),
          na.color = "blue",
          cexRow = 0.5,
          cexCol = .7,
          main = "DE geness",
          Colv = F)

当没有 NaN 值时,这很有效,但是当数据有 NaN 时,我收到一条错误消息:

Error in hclustfun(distfun(x)) : 
  NA/NaN/Inf in foreign function call (arg 11)

基本上,我想让它忽略数据中的NaN。我不确定如何处理。任何帮助将不胜感激。

【问题讨论】:

  • 只需将 NA 转换为其他范围之外的数字,并指定符合您需要的中断和调色板。
  • 鉴于下面的不可再现性答案,首先确保您的“NaN”是真正的NaN,而不是字符串或其他一些垃圾。然后验证您在heatmap.2 调用中调用的每个函数是否返回您期望的数据类。例如,symbreaks=min(foo2 = 0, na.rm=TRUE) 是一种奇怪的方法来检查 foo2 中是否有任何 0 值。
  • @BondedDust,将 NA 转换为值(即使在 dist 矩阵中)会影响聚类。

标签: r heatmap gplots


【解决方案1】:

TL;DR:问题可能是由于委派的distfun 而不是heatmap2 函数本身。默认的 dist 函数尝试计算数据点之间的距离,如果距离计算返回 NA,则聚类函数无法处理。


更长的版本:

我最近遇到了与 OP 相同的问题,并且不得不深入研究以了解为什么其他人无法重现该问题。

本质问题如下:heatmap2默认传递hclusthclustfundist作为distfun参数。错误消息清楚地表明它是hclustfun(在这种情况下默认为hclust)不喜欢NAs。

下一点信息是这样的:即使数据矩阵包含NAs,dist(传递给hclust)的结果可能没有 NA,@kdauria 的情况就是这样回答。见下文:

> library(gplots)
> mat = matrix( rnorm(25), 5, 5)
> mat[c(1,6,8,11,15,20,22,24)] = NaN
> 
> heatmap.2( mat,
+            col = colorpanel(100,"red","yellow","green"),
+            margins = c(12, 22),
+            trace = "none", 
+            xlab = "Comparison",
+            lhei = c(2, 8),
+            scale = c("none"),
+            symbreaks = min(mat, na.rm=TRUE),
+            na.color="blue",
+            cexRow = 0.5, cexCol = 0.7,
+            main = "DE genes", 
+            dendrogram = "row", 
+            Colv = FALSE )
> ?dist
> mat
           [,1]       [,2]        [,3]        [,4]       [,5]
[1,]        NaN        NaN         NaN -1.10103187 -1.4396185
[2,] -0.8821449  1.4891180  0.41956063 -0.06442867        NaN
[3,] -2.5912928        NaN -0.56603029 -0.55177559 -2.0313602
[4,]  0.8348197  0.2199583  0.06318663  1.59697764        NaN
[5,] -0.2632078 -1.2193110         NaN         NaN  0.8618543
> dist(mat)
         1        2        3        4
2 2.317915                           
3 1.276559 2.623637                  
4 6.032933 3.050821 5.283828         
5 5.146250 4.392798 5.871684 2.862324

随机值矩阵不会重现问题,因为它避免了手头的问题。这让我想到了一个问题:dist 获得 NA 需要什么?


我的数据有一些异常大的值,我认为这是原因,但是我只能通过添加一行 NA 来重现问题:

> mat = matrix(rnorm(49), 7, 7)
> mat[c(3,17,28, 41)] = mat[c(3,17,28, 41)] * 100000
> mat
              [,1]        [,2]          [,3]          [,4]        [,5]          [,6]       [,7]
[1,] -6.175928e-01  1.68691561 -1.233250e+00 -7.355322e-01 -0.37392178  3.559804e-01  1.7536137
[2,]  6.680429e-01  0.90590237 -1.375424e+00  5.842512e-01 -0.09376548 -3.556098e-01 -1.2926535
[3,] -3.739372e+04 -1.74534887 -2.241643e+05 -2.209226e-01 -0.86769435 -4.590908e-01  1.6306854
[4,] -1.283405e+00  0.20698245  3.635557e-01  3.673208e-01 -0.12339047  1.119922e+00  0.4301094
[5,] -5.430687e-02 -0.75219479  2.609126e+00 -1.340564e-01  0.54016622  2.885021e-01  0.9237946
[6,] -8.395116e-01  0.03675002  2.455545e+00  4.432025e-02 -0.86194910  1.302758e+05  0.6062505
[7,]  1.817036e-01 -1.46137388 -1.853179e+00 -2.177306e+03  2.36763806 -2.273134e+00  1.2440088
> dist(mat)
             1            2            3            4            5            6
2 3.726858e+00                                                                 
3 2.272605e+05 2.272606e+05                                                    
4 2.966078e+00 3.537475e+00 2.272620e+05                                       
5 4.787577e+00 5.039154e+00 2.272644e+05 3.016614e+00                          
6 1.302754e+05 1.302762e+05 2.619559e+05 1.302747e+05 1.302755e+05             
7 2.176576e+03 2.177895e+03 2.272705e+05 2.177679e+03 2.177179e+03 1.302963e+05
> mat = rbind(mat[1:4, ], rep(NA,7), mat[5:6, ])
> mat
              [,1]        [,2]          [,3]        [,4]        [,5]          [,6]       [,7]
[1,] -6.175928e-01  1.68691561 -1.233250e+00 -0.73553223 -0.37392178  3.559804e-01  1.7536137
[2,]  6.680429e-01  0.90590237 -1.375424e+00  0.58425125 -0.09376548 -3.556098e-01 -1.2926535
[3,] -3.739372e+04 -1.74534887 -2.241643e+05 -0.22092261 -0.86769435 -4.590908e-01  1.6306854
[4,] -1.283405e+00  0.20698245  3.635557e-01  0.36732078 -0.12339047  1.119922e+00  0.4301094
[5,]            NA          NA            NA          NA          NA            NA         NA
[6,] -5.430687e-02 -0.75219479  2.609126e+00 -0.13405635  0.54016622  2.885021e-01  0.9237946
[7,] -8.395116e-01  0.03675002  2.455545e+00  0.04432025 -0.86194910  1.302758e+05  0.6062505
> dist(mat)
             1            2            3            4            5            6
2 3.726858e+00                                                                 
3 2.272605e+05 2.272606e+05                                                    
4 2.966078e+00 3.537475e+00 2.272620e+05                                       
5           NA           NA           NA           NA                          
6 4.787577e+00 5.039154e+00 2.272644e+05 3.016614e+00           NA             
7 1.302754e+05 1.302762e+05 2.619559e+05 1.302747e+05           NA 1.302755e+05
> heatmap.2( mat,
+            col = colorpanel(100,"red","yellow","green"),
+            margins = c(12, 22),
+            trace = "none", 
+            xlab = "Comparison",
+            lhei = c(2, 8),
+            scale = c("none"),
+            symbreaks = min(mat, na.rm=TRUE),
+            na.color="blue",
+            cexRow = 0.5, cexCol = 0.7,
+            main = "DE genes", 
+            dendrogram = "row", 
+            Colv = FALSE )
Error in hclustfun(distfun(x)) : 
  NA/NaN/Inf in foreign function call (arg 11)

但是,这种情况似乎并不特定于行完全由 NA 组成的情况。例如:

> mat
              [,1]        [,2]          [,3]       [,4]       [,5]          [,6]       [,7]
[1,]           NaN         NaN           NaN        NaN         NA -7.531027e-01  0.2238252
[2,]  3.210084e-01 -1.55702840  2.777516e-01  0.2176875  1.3310334 -9.621561e-01        NaN
[3,]  1.159837e+05  0.04480172 -1.649482e+04        NaN  2.4748122  8.446133e-01 -0.4240776
[4,] -8.584051e-01         NaN           NaN  1.0557713 -1.0855826 -5.638023e-02 -0.3789979
[5,]            NA          NA -2.539003e-01 -0.4552776  0.3856384            NA         NA
[6,]           NaN  1.31986556           NaN -1.0393147 -1.9197183 -1.434064e+00  0.6334569
[7,]           NaN -0.42180912           NaN -0.8023476 -0.8264077  4.471358e+04  0.5046408
> dist(mat)
             1            2            3            4            5            6
2 5.531033e-01                                                                 
3 3.225471e+00 1.386143e+05                                                    
4 1.723619e+00 3.913983e+00 1.534332e+05                                       
5           NA 1.949799e+00 3.085851e+04 3.945524e+00                          
6 1.486699e+00 6.010961e+00 6.905415e+00 3.743585e+00 4.449179e+00             
7 8.365286e+04 5.915178e+04 5.914939e+04 5.915058e+04 2.358664e+00 5.290752e+04

【讨论】:

    【解决方案2】:

    所以我根本不是编码专家,但我一直在学习在 R 上制作热图,并且我的 NA 数据一直有相同的错误消息。事实证明,我收到错误消息的原因是我的数据的第一列中有 NA 项,而 R 根本不喜欢这样。所以我添加了一个额外的列并用 1 填充它并且它有效! 我希望也许有人会觉得这很有用!

    卡西娜

    【讨论】:

    • 您应该在答案中添加更多细节。以 1 为例。
    • @Simon Kahina 的解决方案意味着向矩阵添加一列相同的值。因此,与矩阵一样多的 1 有行。此解决方案可以计算所有行向量之间的欧几里得距离,但会添加一个对结果图没有解释的列。
    【解决方案3】:

    除了 posdef 非常有启发性的答案之外,只是一个实用解决方案的建议:

    由于 distfun 仅用于确定树状图的结构,您可以简单地将 dist 矩阵中的 NA 替换为略高于非 NA 值最大值的值。

    为此,我们需要一个新的距离函数(一个包装普通 dist 函数并仅替换 NA 的函数):

    dist_no_na <- function(mat) {
        edist <- dist(mat)
        edist[which(is.na(edist))] <- max(edist, na.rm=TRUE) * 1.1 
        return(edist)
    }
    

    并在 heatmap.2 调用中使用此函数:

    heatmap.2(mat, ..., dendrogram="row", Colv="NA", na.color="black", distfun=dist_no_na)
    

    属性

    这当然不是一个完美的解决方案。它将数值距离值分配给没有可以计算(欧几里得?)距离的基础的向量对。但是,它确实具有一些理想的特性。

    1. heatmap.2 功能有效 :-)

    2. 例如,仅包含 NA 的行然后首先从主分支中拆分(这很好地反映了手头的问题)。

    3. 我不完全确定它具有哪种效果来替换由矩阵的其他属性引起的 NA 值。 posdef 指出可能存在这样的 NA 值。在 posdef 的示例中,有两行在同一列中没有一对非 NA 条目 - 即不可能确定欧几里德距离。在这种情况下,可能仍然适合将其反映为比所有可以数值计算的距离都大的特别大的距离。

    我不会选择比非 NA 最大值大得多的替换值。 (上面代码中选择的值大 10%。)这将增加所有 NA 行的分离点到以下分离点(树状图的相关部分)的距离,并可能使相关部分树状图很难看到。

    【讨论】:

      【解决方案4】:

      如果这似乎是我过度简化它,我深表歉意,但我知道我会喜欢这样的简化帖子(因为我不是 R 专家)。我发现这是迄今为止最简单的方法,我会用我的数据来展示它;

      我的数据范围从 0 到 114 的数据矩阵中有很多 NA 值,所以我首先将所有 NA 值替换为 -1(低于我的数据集范围)

      x <- mymatrix %>% replace(is.na(.), -1)
      

      然后我使用 heatmap.2() 设置休息时间。如果您希望您的 NA 值是“黑色”,其余值使用具有一系列颜色的调色板,则使用 seq() 设置您的中断。由于我的数据范围从 0 到 114,我将 seq 设置为以 1 为增量从 0 到 114。然后使用 heatmap.2() 我将中断设置为 -1,然后设置我的序列(所以中断看起来像( -1,0,1,2,3..等)。我将 -1 值(NA)的颜色设置为“黑色”,并使用 bluered 调色板中的 114 种颜色作为其余值。

      seq <- seq(from = 0, to = 114, by = 1)
      heatmap.2(x, col = c("black", bluered(114)), 
            trace = "none", density.info = "none", breaks=c(-1,seq))
      

      我希望这会有所帮助!

      【讨论】:

        【解决方案5】:

        我无法重现该问题。下面的代码工作得很好。所有的 NaN 值都是蓝色的。

        library(gplots)
        mat = matrix( rnorm(25), 5, 5)
        mat[c(1,6,8,11,15,20,22,24)] = NaN
        
        heatmap.2( mat,
                   col = colorpanel(100,"red","yellow","green"),
                   margins = c(12, 22),
                   trace = "none", 
                   xlab = "Comparison",
                   lhei = c(2, 8),
                   scale = c("none"),
                   symbreaks = min(mat, na.rm=TRUE),
                   na.color="blue",
                   cexRow = 0.5, cexCol = 0.7,
                   main = "DE genes", 
                   dendrogram = "row", 
                   Colv = FALSE )
        

        【讨论】:

        • 不过,这似乎有点误导用作调色板,因为蓝色只是您选择的调色板的延伸......当然黑色或白色会是更好的选择?
        • 这个例子没有反映 OP 最有可能遇到的情况,因为它没有复制dist(mat) 包括NAs 的情况。请参阅下面的答案
        猜你喜欢
        • 2020-09-10
        • 2019-09-19
        • 2022-11-11
        • 2022-09-23
        • 2017-09-19
        • 1970-01-01
        • 1970-01-01
        • 2019-10-01
        • 2020-07-16
        相关资源
        最近更新 更多