【问题标题】:R: Error when setting colors for multiple plots using ggplot2 and marrangeGrobR:使用 ggplot2 和 marrangeGrob 为多个绘图设置颜色时出错
【发布时间】:2016-12-16 20:26:52
【问题描述】:

随着时间的推移,我需要为研究中的各个受试者绘制大量药物浓度图,并且我想根据他们服用的药物始终如一地设置颜色。不过,并非所有患者都服用相同的药物。这是我尝试过的:

library(plyr)
library(ggplot2)
library(gridExtra)

A <- data.frame(Time = seq(0, 20, 5),
            DrugConcentration = 100*exp(-0.25*seq(0, 20, 5)),
            Drug = "Midazolam")

B <- data.frame(Time = rep(seq(0, 20, 5), 2),
                DrugConcentration = c(100*exp(-0.25*seq(0, 20, 5)),
                                      75*exp(-0.1*seq(0, 20, 5))),
                Drug = rep(c("Midazolam", "Dextromethorphan"), each = 5))

C <- data.frame(Time = rep(seq(0, 20, 5), 3),
                DrugConcentration = c(100*exp(-0.25*seq(0, 20, 5)),
                                      75*exp(-0.1*seq(0, 20, 5)),
                                      50*exp(-0.15*seq(0, 20, 5))),
                Drug = rep(c("Midazolam", "Dextromethorphan", "Tolbutamide"), 
                           each = 5))

D <- data.frame(Time = rep(seq(0, 20, 5), 2),
                DrugConcentration = c(100*exp(-0.25*seq(0, 20, 5)),
                                      50*exp(-0.15*seq(0, 20, 5))),
                Drug = rep(c("Midazolam", "Tolbutamide"), 
                           each = 5))

DrugList <- list(A, B, C, D)

MyColors <- data.frame(Drug = c("Midazolam", "Dextromethorphan", "Tolbutamide"),
                       Color = c("red", "green", "blue"),
                       stringsAsFactors = FALSE)

PlotList <- list()

for(i in 1:length(DrugList)){
      DrugList[[i]] <- arrange(DrugList[[i]], Drug, Time)
      MyColors.temp <- join(DrugList[[i]][, c("Drug", "Time")], 
                        MyColors, by = "Drug")
      MyColors.temp <- unique(MyColors.temp[, c("Drug", "Color")])
      MyColors.temp <- arrange(MyColors.temp, Drug)

      PlotList[[i]] <- 
          ggplot(DrugList[[i]], 
               aes(x = Time, y = DrugConcentration, 
                   color = Drug)) +
          geom_point() + geom_line() +
          scale_color_manual(values = MyColors.temp$Color)
}

循环运行,但是当我尝试时

marrangeGrob(PlotList, nrow = 2, ncol = 2)

我得到错误:Insufficient values in manual scale. 3 needed but only 2 provided. 如果我单独查看每个图,例如,通过键入 PlotList[[1]],前两个图至少会生成图(尽管每种药物的颜色不一致,而不是我指定),但第三个是给我关于没有足够值的错误的那个。

这是第一个图,咪达唑仑的颜色正确:

这是第二个情节,它没有正确的颜色:

这里发生了什么?为什么这不起作用?

【问题讨论】:

    标签: r ggplot2 gridextra


    【解决方案1】:

    为什么这不起作用?

    情节 3 是问题所在 - 不是其本身,而是与 for 循环和 ggplot2 的惰性求值机制相结合。当您定义每个绘图时,ggplot2 会正确捕获第 i 个数据集的环境,但手动比例存储为未评估的承诺。当它最终被评估时(在绘图前不久调用 ggplot_build 时),MyColors.temp 只有两个值(循环的最新迭代),并且情节 3 抱怨手动比例提供的值太少。

    为什么色阶不一致?

    scale_colour_manual 需要一个命名向量,而不是一对值——断点(在我阅读帮助页面之前,它确实欺骗了我!)。

    有几种可能的解决方案。

    将整组颜色作为命名向量传递

    MyColors <- c("Midazolam" = "red", "Dextromethorphan" = "green", "Tolbutamide" = "blue")
    
    DrugList <- list(A, B, C, D)
    
    PlotList <- list()
    
    for(i in 1:length(DrugList)){
    
      PlotList[[i]] <- 
        ggplot(arrange(DrugList[[i]], Drug, Time), 
               aes(x = Time, y = DrugConcentration, 
                   color = Drug)) +
        geom_point() + geom_line()  +
        scale_colour_manual(values = MyColors) +
        theme()
    }
    
    grid.arrange(grobs=PlotList)
    

    刻面

    m <- reshape2::melt(DrugList, measure.vars = "DrugConcentration")
    str(m)
    
    p <- ggplot(m, aes(x = Time, y = value, color = Drug)) +
      facet_wrap(~L1) +
      geom_point() + geom_line() +
      scale_colour_manual(values = MyColors)
    

    ggforce 似乎提供了可以扩展到多个页面的分面功能。使用额外的虚拟变量将整个数据集分成组以绘制为单独的 2x2 面也很容易实现。

    拆分申请

    如果您需要单独的绘图,使用长格式 data.frame 也更容易,

    lp <- plyr::dlply(m, "L1", function(d) p %+% d)
    
    grid.arrange(grobs = lp)
    

    【讨论】:

    • 因为我有大约 8000 张图表,我需要我可怜的本科研究助理仔细寻找可能的数据输入错误。我需要很多页面,但我无法处理那么多图表。
    • IIRC 最近有一个实现多页面方面的包
    • 多页面的多面图解决方案会很棒!
    • 另外,您展示的第二组图表也存在我遇到的相同问题,即每种药物的颜色不一致。
    • 我正在研究您的解决方案...这部分有什么作用? function(d) p %+% d
    猜你喜欢
    • 2017-12-28
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 2018-03-26
    • 1970-01-01
    相关资源
    最近更新 更多