Сохраните тепловую карту.2 в переменной и снова постройте график

Я использую Heatmap.2 из gplots, чтобы сделать тепловую карту:

library(gplots)
# some fake data
m = matrix(c(0,1,2,3), nrow=2, ncol=2)
# make heatmap
hm = heatmap.2(m)

Когда я делаю 'heatmap.2' напрямую, я получаю график, который могу вывести на устройство. Как я могу снова сделать график из моей переменной «хм»? Очевидно, что это игрушечный пример, в реальной жизни у меня есть функция, которая генерирует и возвращает тепловую карту, которую я хотел бы построить позже.


person Martin Preusse    schedule 13.05.2013    source источник


Ответы (2)


Есть несколько альтернатив, хотя ни одна из них не отличается особой элегантностью. Это зависит от того, доступны ли переменные, используемые вашей функцией, в среде построения. 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-поле. Чтобы получить исходную матрицу, требуется немного поработать, поскольку проекция была:

# 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 создает исходный график.

person Teemu Daniel Laajala    schedule 14.05.2013
comment
Спасибо, это было исчерпывающе ;) В моем случае "тепловая карта.2(t(hm2$carpet))" работает хорошо. Я действительно не понимаю, что означают «revRowInd» и «revColInd». Когда я рисую в своей функции, а затем просто с помощью «heatmap.2 (t (hm2 $ carpet))», это выглядит одинаково. - person Martin Preusse; 14.05.2013
comment
Хорошо, отлично :) В моем искусственном примере это не дало такого же результата, если я не реконструировал строки/столбцы, поэтому вы должны убедиться, что в вашем случае он обобщается на каждый график, который вы делаете. Возможно, у вас есть симметричная матрица или какой-то другой параметр (например, отсутствие переупорядочения строк/столбцов) отрицает это. - person Teemu Daniel Laajala; 14.05.2013
comment
Спасибо, теперь я понял, что вы сделали. Я проверю, если мне это нужно ;) - person Martin Preusse; 14.05.2013

Я бы сделал функциональное программирование:

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

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

show_heatmap <- create_heatmap(x = data)

show_heatmap()

Передайте все аргументы, которые вам нужно отправить в plot_heatmap, через файл .... Вызов внешней функции устанавливает среду, в которой внутренняя функция сначала ищет свои аргументы. Внутренняя функция возвращается как объект и теперь полностью переносима. Это должно давать один и тот же сюжет каждый раз!

person scooteR    schedule 04.10.2013