这可能是一个非常微不足道的问题,但我更习惯于蟒蛇而不是R(事实上我主要是生物学家也可能扮演一个角色......)
以下代码的作用是在独立面板中绘制所提供数据中每个基因的计数,并重新排列图例,以便为图中的所有面板分配一个。
# function to rearrange plot legend, from here:
# http://rpubs.com/sjackman/grid_arrange_shared_legend. Give credit where credit is due ;)
grid_arrange_shared_legend <- function(...) {
plots <- list(...)
g <- ggplotGrob(plots[[1]] + theme(legend.position="bottom"))$grobs
legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]]
lheight <- sum(legend$height)
grid.arrange(
do.call(arrangeGrob, lapply(plots, function(x)
x + theme(legend.position="none"))),
legend,
ncol = 1,
heights = unit.c(unit(1, "npc") - lheight, lheight))
}
# make plot for the given gene and assign it to a named object
plot_genes <- function(gene, gID){
name<-paste0("plotted_counts_for_", gene)
counts = plotCounts("whatever") # get data using plotCounts from DESeq2 package. the gID is used in here
return(assign(name, ggplot(counts,
# + a bunch of plotting aestetics
envir = .GlobalEnv)) #make plot available outside function. Probably I can also use parent.frame()
}
# call plot_genes() for each cluster of genes, adjust the legend for multiple plots with grid_arrange_shared_legend()
plot_cluster_count <- function(cluster,name) {
genes = as.vector(as.data.frame(cluster)$Symbol)
gIDs = as.vector(as.data.frame(cluster)$EMSEMBL)
pdf(paste0(name,"_counts.pdf"))
plt = lapply(seq_along(genes), function(x) plot_genes(genes[x], gIDs[x]))
grid_arrange_shared_legend(plotted_counts_for_gene1, plotted_counts_for_gene2, plotted_counts_for_gene3,plotted_counts_for_gene4)
dev.off()
}
# call the whole thing
plot_cluster_count(Cluster_1,"Cluster_1")
此代码有效。
问题是,只有当我明确地对grid_arrange_shared_legend(plotted_counts_for_gene1, plotted_counts_for_gene2, plotted_counts_for_gene3,plotted_counts_for_gene4)
中的图表名称进行硬编码时,它才有效。
但是我有很多聚类要绘制,不同数量的基因具有不同的名称,所以我需要自动选择要提供给grid_arrange_shared_legend()
的对象。
我尝试使用ls()/objects()
,mget()
和谷歌,但我找不到让它运转的方法,我总是最终得到
Error in plot_clone(plot) : attempt to apply non-function
。
我用options(error=recover)
追溯了错误,实际上它来自grid_arrange_shared_legend()
,所以对我而言,我似乎无法将对象提供给函数。
最终目标是能够在plot_cluster_count()
语句中调用lapply()
来提供群集列表以进行迭代。这应该导致每个簇一个pdf,每个基因包含一个面板。
PS 我知道从环境中获取对象名称并不是最优雅的方式,它看起来更简单。任何替代方法都非常受欢迎
谢谢!
答案 0 :(得分:0)
一个解决方案:
# mock data (3 "objects")
set.seed(1)
obj_1 <- list(var = sample(1:100, 1), name = "obj_1")
obj_2 <- list(var = sample(1:100, 1), name = "obj_2")
obj_3 <- list(var = sample(1:100, 1), name = "obj_3")
# any kind of function you want to apply
f1 <- function(obj, obj_name) {
print(paste(obj, " -- ", obj_name))
}
# Find all objects in your environment
list_obj <- ls(pattern = "obj_")
# Apply the previous function on this list
output <- lapply(list_obj, function(x) f1(get(x)$var, get(x)$name))
output
#> [[1]]
#> [1] "27 -- obj_1"
#>
#> [[2]]
#> [1] "38 -- obj_2"
#>
#> [[3]]
#> [1] "58 -- obj_3"