繁体   English   中英

R从环境中获取对象并提要功能

[英]R Get objects from environment and feed to function

这可能是一个相当琐碎的问题,但是我比R更加习惯于python(事实上我主要是生物学家也可能起着作用……)

下面的代码要做的是在一个独立的面板中绘制提供的数据中每个基因的计数,并重新排列图例,以使图中的所有面板都只有一个。

# 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(plotted_counts_for_gene1, plotted_counts_for_gene2, plotted_counts_for_gene3,plotted_counts_for_gene4) 但是,我要绘制很多簇,具有不同名称的不同数量的基因,因此我需要自动选择要馈送到grid_arrange_shared_legend()的对象。

我试图与ls()/objects()mget()和Google一起玩,但是我找不到一种使它正常工作的方法,我总是Error in plot_clone(plot) : attempt to apply non-function 我使用options(error=recover)追溯了错误,并且确实来自grid_arrange_shared_legend() ,所以对我来说似乎无法将对象提供给函数。

最终目标是能够在lapply()语句中调用plot_cluster_count() ,从而提供要迭代的集群列表。 这将导致每个簇一个pdf,每个基因每个包含一个面板。

PS我知道从环境中获取对象名称并不是最优雅的方法,它看起来更加简单。 任何替代方法都值得欢迎

谢谢!

一种解决方案:

# 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"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM