Что-то странное в pheatmap (ошибка?) - PullRequest
0 голосов
/ 20 декабря 2018

Воспроизводимые данные:

data(crabs, package = "MASS")
df <- crabs[-(1:3)]
set.seed(12345)
df$GRP <- kmeans(df, 4)$cluster
df.order <- dplyr::arrange(df, GRP)

Описание данных:

df имеет 5 числовых переменных.Я сделал алгоритм K-средних согласно этим 5 атрибутам и создал новую категориальную переменную GRP, которая имеет 4 уровня.Затем я заказал его с GRP и назвал его df.order.


Что я сделал с pheatmap:

## 5 numerical variables for coloring
colormat <- df.order[c("FL", "RW", "CL", "CW", "BD")]

## Specify the annotation variable `GRP` shown on left side of the heatmap
ann_row <- df.order["GRP"]

## gap indices
gapRow <- cumsum(table(ann_row$GRP))

library(pheatmap)
pheatmap(colormat, cluster_rows = F, show_rownames = F,
         annotation_row = ann_row, gaps_row = gapRow)

Ошибка в annotation_colors [[colnames (annotation) [i]]]: индекс за пределами границ


Вот где я получил что-то странное:

Сначала я предполагаю, что проблема возникла из аргумента annotation_row. Я проверяю имена строк двух фреймов данных.

all.equal(rownames(colormat), rownames(ann_row))
# [1] TRUE

Вы видите, что они равны.Однако я выполнил следующий код и работу с тепловой картой.

rownames(colormat) <- rownames(ann_row)
pheatmap(colormat, cluster_rows = F, show_rownames = F,
         annotation_row = ann_row, gaps_row = gapRow)

Теоретически этот код "rownames(colormat) <- rownames(ann_row)" не должен иметь смысла, потому что эти два объекта изначально равны, но почему он делаетфункция pheatmap() работает?


Редактировать: Из комментария @ steveb мне даже не нужно задавать имена строк с помощью ann_row.Я просто установил

rownames(colormat) <- rownames(colormat)

, и pheatmap также работает.Эта ситуация все еще нелогична.


Конечный результат:

enter image description here

1 Ответ

0 голосов
/ 22 декабря 2018

Короче говоря, colormat не имеет rownames до rownames(colormat) <- rownames(colormat), но имеет rownames после.Этот ответ начинает касаться природы проблемы, но не углубляется в то, почему или как pheatmap сталкивается с этим, или почему R работает таким образом.Другими словами, я не углубляюсь в детали того, как имена строк обрабатываются в R.

Суть этой проблемы связана с rownames, возвращающим вектор по умолчанию для номера строки;каждый элемент является числовым значением, но представлен в виде строки, поэтому строка 10 становится именем строки «10».При использовании attributes(colormat) вы увидите, что $row.names - это числовой вектор до rownames(colormat) <- rownames(colormat) и символьный вектор после (теперь он имеет имена строк).Мне не ясно, почему что-то (кроме NULL или NA) возвращается, когда что-то не имеет установленных имен строк.

attributes(colormat)
## $names
## [1] "FL" "RW" "CL" "CW" "BD"
## 
## $row.names
##   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38
##  [39]  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76
##  [77]  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
## [115] 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
## [153] 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
## [191] 191 192 193 194 195 196 197 198 199 200
## 
## $class
## [1] "data.frame"

rownames(colormat) <- rownames(colormat)

attributes(colormat)
## $names
## [1] "FL" "RW" "CL" "CW" "BD"
## 
## $row.names
##   [1] "1"   "2"   "3"   "4"   "5"   "6"   "7"   "8"   "9"   "10"  "11"  "12"  "13"  "14"  "15"  "16"  "17"  "18"  "19"  "20"  "21"  "22"  "23"  "24"  "25" 
##  [26] "26"  "27"  "28"  "29"  "30"  "31"  "32"  "33"  "34"  "35"  "36"  "37"  "38"  "39"  "40"  "41"  "42"  "43"  "44"  "45"  "46"  "47"  "48"  "49"  "50" 
##  [51] "51"  "52"  "53"  "54"  "55"  "56"  "57"  "58"  "59"  "60"  "61"  "62"  "63"  "64"  "65"  "66"  "67"  "68"  "69"  "70"  "71"  "72"  "73"  "74"  "75" 
##  [76] "76"  "77"  "78"  "79"  "80"  "81"  "82"  "83"  "84"  "85"  "86"  "87"  "88"  "89"  "90"  "91"  "92"  "93"  "94"  "95"  "96"  "97"  "98"  "99"  "100"
## [101] "101" "102" "103" "104" "105" "106" "107" "108" "109" "110" "111" "112" "113" "114" "115" "116" "117" "118" "119" "120" "121" "122" "123" "124" "125"
## [126] "126" "127" "128" "129" "130" "131" "132" "133" "134" "135" "136" "137" "138" "139" "140" "141" "142" "143" "144" "145" "146" "147" "148" "149" "150"
## [151] "151" "152" "153" "154" "155" "156" "157" "158" "159" "160" "161" "162" "163" "164" "165" "166" "167" "168" "169" "170" "171" "172" "173" "174" "175"
## [176] "176" "177" "178" "179" "180" "181" "182" "183" "184" "185" "186" "187" "188" "189" "190" "191" "192" "193" "194" "195" "196" "197" "198" "199" "200"
## 
## $class
## [1] "data.frame"

Это не числовое значение против символьного значения имен строк, которое являетсяпроблема в том, заданы ли имена строк или нет.Если бы вы сделали следующее:

rownames(colormat) <- 1:nrow(colormat)

Вы обнаружите, что это тоже исправит проблему, поскольку rownames теперь имеет числовые значения номера строки (см. attributes(colormat) output).

Если вы используете tibble::has_rownames(colormat) до rownames(colormat) <- rownames(colormat), тогда вы получите FALSE.После назначения вы получите TRUE.

tibble::has_rownames(colormat)
## [1] FALSE
rownames(colormat) <- rownames(colormat)
tibble::has_rownames(colormat)
## [1] TRUE

Я не уверен, как pheatmap использует colormat для внутреннего использования, но это должно быть связано с тем, что rownames не установлен,Если вы обратитесь к авторам этого пакета (возможно, через GitHub: https://github.com/raivokolde/pheatmap),, они могут обновить код для обработки этого углового случая для следующего выпуска.

...