簡體   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