[英]Function to save multiple Complex Heatmap plots with added elements in a list using sapply - R
我正在尝试创建一个带有添加到 plot 元素的热图列表。 我使用的代码源自复杂的热图教程: https://jokergoo.github.io/ComplexHeatmap-reference/book/heatmap-annotations.ZFC35FDC70D5FC69D269883A8
这是我的 function 的简化版本:
library(ComplexHeatmap)
library(GetoptLong) # for the function qq()
make_heatmap <-
function(seed) {
set.seed(seed)
mat2 = matrix(rnorm(50 * 50), nrow = 50)
split = rep(1:5, each = 10)
ha = HeatmapAnnotation(
empty = anno_empty(border = FALSE, height = unit(8, "mm")),
foo = anno_block(gp = gpar(fill = 2:6), labels = LETTERS[1:5])
)
group_block_anno = function(group,
empty_anno,
gp = gpar(),
label = NULL,
label_gp = gpar()) {
seekViewport(qq("annotation_@{empty_anno}_@{min(group)}"))
loc1 = deviceLoc(x = unit(0, "npc"), y = unit(0, "npc"))
seekViewport(qq("annotation_@{empty_anno}_@{max(group)}"))
loc2 = deviceLoc(x = unit(1, "npc"), y = unit(1, "npc"))
seekViewport("global")
grid.rect(
loc1$x,
loc1$y,
width = loc2$x - loc1$x,
height = loc2$y - loc1$y,
just = c("left", "bottom"),
gp = gp
)
if (!is.null(label)) {
grid.text(
label,
x = (loc1$x + loc2$x) * 0.5,
y = (loc1$y + loc2$y) * 0.5,
gp = label_gp
)
}
}
htmp <-
Heatmap(
mat2,
name = "mat2",
column_split = split,
top_annotation = ha,
column_title = NULL
)
print(htmp)
group_block_anno(1:3, "empty", gp = gpar(fill = "red"), label = "group 1")
group_block_anno(4:5, "empty", gp = gpar(fill = "blue"), label = "group 2")
}
然后,我想使用 sapply 将具有不同参数的图保存在列表中:
heatmap.list <- sapply(c(1,10,100,1000), make_heatmap)
通过调用heatmap.list[1]
我希望得到这样的热图:
但是,我的 heatmap.list 的heatmap.list
如下:
heatmap.list
[,1] [,2] [,3] [,4]
label "group 2" "group 2" "group 2" "group 2"
x 6.86002 6.86002 6.86002 6.86002
y 5.88428 5.88428 5.88428 5.88428
just "centre" "centre" "centre" "centre"
hjust NULL NULL NULL NULL
vjust NULL NULL NULL NULL
rot 0 0 0 0
check.overlap FALSE FALSE FALSE FALSE
name "GRID.text.33404" "GRID.text.33501" "GRID.text.33598" "GRID.text.33695"
gp List,0 List,0 List,0 List,0
vp NULL NULL NULL NULL
我尝试在 function 末尾使用recordPlot()
,
make_heatmap <-
function(seed) {
#same as before
.
.
.
print(htmp)
group_block_anno(1:3, "empty", gp = gpar(fill = "red"), label = "group 1")
group_block_anno(4:5, "empty", gp = gpar(fill = "blue"), label = "group 2")
record.htmp <- recordPlot()
plot.new()
record.htmp
}
heatmap.list <- sapply(c(1, 10, 100, 1000), make_heatmap)
但是output如下:
heatmap.list
[,1] [,2] [,3] [,4]
[1,] List,502 List,502 List,502 List,502
[2,] Raw,35992 Raw,35992 Raw,35992 Raw,35992
[3,] List,2 List,2 List,2 List,2
有没有办法获得我想要的热图列表? 我已经搜索了很多,但我找不到解决方案。
编辑解决方案:
正如 Robert Hacken 所建议的,使用lapply()
而不是sapply()
可以解决问题。 我在这里发布了更正后的 function 以解决可能的类似问题:
library(ComplexHeatmap)
library(GetoptLong) # for the function qq()
make_heatmap <-
function(seed) {
set.seed(seed)
mat2 = matrix(rnorm(50 * 50), nrow = 50)
split = rep(1:5, each = 10)
ha = HeatmapAnnotation(
empty = anno_empty(border = FALSE, height = unit(8, "mm")),
foo = anno_block(gp = gpar(fill = 2:6), labels = LETTERS[1:5])
)
group_block_anno = function(group,
empty_anno,
gp = gpar(),
label = NULL,
label_gp = gpar()) {
seekViewport(qq("annotation_@{empty_anno}_@{min(group)}"))
loc1 = deviceLoc(x = unit(0, "npc"), y = unit(0, "npc"))
seekViewport(qq("annotation_@{empty_anno}_@{max(group)}"))
loc2 = deviceLoc(x = unit(1, "npc"), y = unit(1, "npc"))
seekViewport("global")
grid.rect(
loc1$x,
loc1$y,
width = loc2$x - loc1$x,
height = loc2$y - loc1$y,
just = c("left", "bottom"),
gp = gp
)
if (!is.null(label)) {
grid.text(
label,
x = (loc1$x + loc2$x) * 0.5,
y = (loc1$y + loc2$y) * 0.5,
gp = label_gp
)
}
}
htmp <-
Heatmap(
mat2,
name = "mat2",
column_split = split,
top_annotation = ha,
column_title = NULL
)
print(htmp)
group_block_anno(1:3, "empty", gp = gpar(fill = "red"), label = "group 1")
group_block_anno(4:5, "empty", gp = gpar(fill = "blue"), label = "group 2")
record.htmp <- recordPlot()
plot.new()
record.htmp
}
heatmap.list <- lapply(c(1, 10, 100, 1000), make_heatmap)
编辑2:
heatmap.list <- sapply(c(1, 10, 100, 1000), make_heatmap, simplify = F)
也可以工作,它允许使用heatmap.list$parameter
按名称访问列表的元素,这可能会改善工作流程。
您可以使用lapply
而不是sapply
以便结果不会简化为矩阵,然后使用heatmap.list[[1]]
获取例如第一个元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.