Создание тепловой карты, в которой данные имеют значения NaN в ней

Я пытаюсь создать тепловую карту с помощью пакета 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 в данных. Я не уверен, как справиться с этим. любая помощь будет принята с благодарностью.

Ответ 1

TL; DR: Вероятно, проблема связана с делегированной функцией distfun, а не с функцией heatmap2. Функция dist по умолчанию пытается рассчитать расстояние между вашими точками данных, а если вычисление расстояния возвращает NA, функция кластеризации не сможет справиться с этим.


Более длинная версия:

Недавно я столкнулся с той же проблемой, что и OP, и мне пришлось немного разобраться, чтобы понять, почему проблема не воспроизводится для других.

Существенная проблема заключается в следующем: heatmap2 по умолчанию передает hclust и hclustfun и dist в качестве параметров distfun. В сообщении об ошибке четко указано, что он hclustfun (который в этом случае по умолчанию равен hclust), который не нравится NA s.

Следующий бит информации таков: даже если матрица данных включает NA, результаты dist (которые передаются в hclust) могут быть свободны от НС, что имеет место для ответа @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

Случайнозначная матрица не воспроизводит проблему, поскольку она позволяет избежать проблемы. Это подводит меня к вопросу: что нужно, чтобы получить NA из dist?


У моих данных были некоторые большие большие значения, которые, как я думал, были причиной, однако мне удалось воспроизвести проблему, добавив строку 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, и она сработала! Я надеюсь, что кто-то найдет это полезным!

Кахина

Ответ 3

Просто предложение для практического решения в дополнение к posdef очень поучительный ответ:

Поскольку distfun используется только для определения структуры дендрограммы, вы можете просто заменить NA в матрице dist значениями, которые немного превышают максимум значений, не относящихся к 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, которые вызваны другими свойствами матрицы. Посдеф указал, что могут быть такие значения NA. В примере posdef есть две строки, для которых нет пары не-NA записей в одном и том же столбце - т.е. невозможно определить евклидово расстояние. В этом случае, вероятно, все еще целесообразно отразить это как особо большое расстояние, большее, чем все те, которые могут быть вычислены численно.

Я бы не выбрал заменяющее значение, намного большее, чем максимум, не связанный с NA. (Выбранное значение в приведенном выше коде на 10% больше.) Это увеличит расстояние от точки разделения строк всех NA до следующих точек разделения (соответствующая часть дендрограммы) и может сделать соответствующую часть дендрограммы трудно увидеть.

Ответ 4

Я не могу воспроизвести проблему. Код ниже работает просто отлично. Все значения 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 )

enter image description here