将不均匀数量的图与for循环和grid.arrange组合在一起

时间:2016-09-12 21:09:44

标签: r for-loop ggplot2

我有数百个用前一个for循环制作的图,这些图以一致的方式命名。这些图是嵌套在中的几个任务的结果。

我想使用grid.arrange在同一个图上绘制定义域的所有任务。

解释我的数据和图表结构的虚拟数据:

domain_key <- data.frame(domain = c("soe", "soe", "soe", "elit", "elit"), 
                     tasks = c("personal", "size", "shapeid", "onetoone", "puzzle"))

dummy <- ggplot(data.frame()) + geom_point() + xlim(0, 10) + ylim(0, 100)

plot.personalpct <- dummy + ggtitle("plot.personalpct")
plot.sizepct <- dummy  + ggtitle("plot.sizepct")
plot.shapeidpct <- dummy  + ggtitle("plot.shapeidpct")
plot.onetoonepct <- dummy  + ggtitle("plot.onetoonepct")
plot.puzzlepct <- dummy  + ggtitle("plot.puzzlepct")

以下是我如何做到的基本想法:

for(j in domain_key$domain){
  tasks <- unique(with(domain_key, tasks[domain == j])) #Get a list of the unique tasks for the domain
  plots <- paste("plot.", tasks, "pct", sep ="") #Get the name of the plots as a character vector
  grid.arrange(eval(parse(text = plots))) #evaluate the expression with grid arrange to display all the plots
}

我的问题是最后一个参数只显示每个域的第一个图。这是因为我的字符向量不会解析为多个对象,可能是因为它们没有用逗号分隔。我尝试了一些变通方法,但无法找到解决方法。或许我的方法完全不合适。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

也许这有帮助

library(ggplot2)
library(gridExtra)

dummy_plot <- function(id, fill) ggplot() + ggtitle(id) + 
  theme(panel.background = element_rect(fill = fill))

pl = list(`domain 1` = lapply(1:3, dummy_plot, fill = "#FBB4AE"),
          `domain 2` = lapply(1:2, dummy_plot, fill = "#B3CDE3"),
          `domain 3` = lapply(1:4, dummy_plot, fill = "#CCEBC5"),
          `domain 4` = lapply(1:5, dummy_plot, fill = "#DECBE4"))

dummy_group <- function(domain) arrangeGrob(grobs = pl[[domain]], top = domain)
grid.arrange(grobs = lapply(names(pl), dummy_group))

enter image description here

答案 1 :(得分:0)

感谢@baptiste和@lukeA的帮助。他们的两个建议都没有完全回答我的问题,但帮助我走上了正确的道路。

我意识到我真的需要为grid.arrange提供一个列表,所以我找到了一个合理但不是非常优雅的解决方案。我在任务的绘图名称中嵌入了名称。然后我使用grep和域名输入grid.arrage和图表列表。这种方法运作得相当好。

这有点太多细节,但说明了我的解决方案:

### Graph means of tasks by treatment group with error bars

pltList <- list() #Create and empty list to store task plots

for(outcome in unique(domain_key$task) ){
  df <- data.frame(Intervention.Group = factor(unique(children$treatment)), 
                 Percent.Correct = eval(parse(text = paste0("meansbytreatment$", outcome, "$estimates"))),
                 SE = eval(parse(text = paste0("meansbytreatment$", outcome, "$se")))) 
  df$upper <- df$Percent.Correct + 2*df$SE
  df$lower <- df$Percent.Correct - 2*df$SE #Make a temp df with with the estimates and errors for each treatment group

  domain <- unique( domain_key$domain[domain_key$task == outcome] ) #extract the domain that the task belongs to
  pltName <- paste( "plot", outcome, domain, sep = "." ) #Make a unique plot name with task and domain

  pltList[[ pltName ]] <- ggplot(df, aes(Intervention.Group, Percent.Correct, fill = Intervention.Group)) +
    geom_bar(stat = "identity") + 
    geom_errorbar(aes(ymin = lower, ymax = upper), width = 0.4) +
    ggtitle(paste(outcome, "by Intervention Group") )+ 
    theme(legend.position="none") #Save the plot to the plot list 
}

### Graph domain subtasks together

Domainplt <- lst() #Make an empty list to store plots of all the taks in a domain

for(j in unique(domain_key$domain)){
  plots <- grep(j, names(pltList)) #get all of the plots from the domain
  nplots <- length(plots) # get the n of plots for the domain
  Domainplt[[j]] <- grid.arrange(grobs = pltList[plots],
                                 ncol = nplots,
                                 top =  j) #Arrange all of the plots horizontally
}