简体   繁体   English

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

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

This is probably a pretty trivial question, but I'm much more used to python than to R (the fact I'm mostly a biologist might also play a role...) 这可能是一个相当琐碎的问题,但是我比R更加习惯于python(事实上我主要是生物学家也可能起着作用……)

What the code below does is plot the counts for each gene in the provided data in an independent panel, and rearrange the legends in order to have a single one for all the panels in the plot. 下面的代码要做的是在一个独立的面板中绘制提供的数据中每个基因的计数,并重新排列图例,以使图中的所有面板都只有一个。

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

This code works. 此代码有效。 The issue is that it works only when I explicitely hard-code the names of the plots as in 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(plotted_counts_for_gene1, plotted_counts_for_gene2, plotted_counts_for_gene3,plotted_counts_for_gene4) However I have plenty of clusters to plot, with different number of genes with different names, so I need to automate the selection of objects to feed to grid_arrange_shared_legend() . 但是,我要绘制很多簇,具有不同名称的不同数量的基因,因此我需要自动选择要馈送到grid_arrange_shared_legend()的对象。

I tried to play around with ls()/objects() , mget() and Google but I can't find a way to get it working, I always end up with Error in plot_clone(plot) : attempt to apply non-function . 我试图与ls()/objects()mget()和Google一起玩,但是我找不到一种使它正常工作的方法,我总是Error in plot_clone(plot) : attempt to apply non-function I traced the error back with options(error=recover) and indeed it comes from grid_arrange_shared_legend() , so to me it looks like I'm not able to feed the objects to the function. 我使用options(error=recover)追溯了错误,并且确实来自grid_arrange_shared_legend() ,所以对我来说似乎无法将对象提供给函数。

The ultimate goal would be to be able to call plot_cluster_count() within a lapply() statement feeding a list of clusters to iterate through. 最终目标是能够在lapply()语句中调用plot_cluster_count() ,从而提供要迭代的集群列表。 This should result in one pdf per cluster, each containing one panel per gene. 这将导致每个簇一个pdf,每个基因每个包含一个面板。

PS I'm aware that getting the object names from the environment is not the most elegant way to go, it just seemed more straightforward. PS我知道从环境中获取对象名称并不是最优雅的方法,它看起来更加简单。 Any alternative approach is more than welcome 任何替代方法都值得欢迎

Thanks! 谢谢!

One solution: 一种解决方案:

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

相关问题 Cbind 在 R 中获取环境对象 - Cbind get environment objects in R 如何从R中的函数将对象加载到当前环境? - How do I load objects to the current environment from a function in R? 从R中的环境中删除对象 - Deleting objects from environment in R (R) 将 Environment 上的对象循环到函数中并导出结果 - (R) Loop objects on Environment into a function and export results 循环/或应用 function 将 igraph 对象列表馈送到 R 中的 function - Loop/ or apply function to feed list of igraph objects into function in R R中如何获取调用函数环境中的对象? - How to obtain objects in the environment of the calling function in R? 将函数应用于我的全局环境 R 中的对象 - Apply a function to objects in my global environment R 如何在R中创建函数以从全局环境中删除除默认值和作为参数传递的对象之外的所有对象 - how to make function in R to remove all objects from global environment except defaults and objects passed as arguments 使用 mcmapply 从父函数调用的嵌套函数内部将 R 对象保存到全局环境 - Saving R objects to global environment from inside a nested function called by a parent function using mcmapply 循环使用全局环境中的对象(R) - Working with objects from Global Environment in loops (R)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM