R从环境中获取对象并将Feed提供给函数

时间:2018-05-30 08:02:03

标签: r ggplot2

这可能是一个非常微不足道的问题,但我更习惯于蟒蛇而不是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 我知道从环境中获取对象名称并不是最优雅的方式,它看起来更简单。任何替代方法都非常受欢迎

谢谢!

1 个答案:

答案 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"