【问题标题】:Assigning corresponding color values to final model variables to be graphed in ggplot (with geom_col) in R将相应的颜色值分配给要在 R 中的 ggplot(使用 geom_col)中绘制的最终模型变量
【发布时间】:2019-11-30 19:37:30
【问题描述】:

我正在创建一组 geom_col 图来揭示模型构建过程,其中不同的认知任务变量按它们降低 AIC 的顺序排列。

变量按它们降低 AIC 的顺序添加,并且只有当它们显着 (LRT) 降低 AIC 时才会包含在最终模型中。因此,有四个独立的绩效指标:响应窗口、效率、一致性和心理测量阈值。所以很自然地,有四个最终模型——响应窗口、效率、一致性和心理测量阈值。 (实际上将有八个最终模型,因为这些模型将属于数学和英语标准化测试 DV)。

因此,我希望最终模型中包含的每个认知任务变量都与特定颜色相对应,这样您就可以可视化始终包含在不同绩效测量模型中的变量。也许有某种方法可以使用“ifelse”语句来创建它——如果这个变量,那么红色……等等。

我知道您可能会创建一个与包含的任务变量的特定顺序相对应的颜色值向量,但我正在尝试在这里提升我的编码,虽然八张图可能没有那么多时间,在在您有更多图表的情况下,这可能是一项相当大的投资。出错的机会也少了很多。

该日期涉及 1000 名参与者和四个绩效指标(包括英语和数学类别)。下面,我只是将数学和英语效率数据集作为一个可重复的最小示例。

我使用下面的代码按照它们减少 AIC 的顺序排列包含的任务变量,使用下面的代码和 R color brewer(变量只是认知任务变量,它们对应的 AIC 值在另一列中)。 (我使用我的整个代码来生成下面的图表,因为有时人们会得到有用的反馈并提供更有效的方法,但你可以忽略它的下半部分)。

非常感谢!感恩节快乐。

efficiency.english<-structure(list(variables = structure(c(3L, 8L, 7L, 5L, 1L, 6L, 
4L, 2L), .Label = c("Con, Filter", "Con, SAAT, Sustained", "Demographics", 
"SAAT, Impulsive", "STROOP, Congruent", "Tap and Trace, Tap", 
"TASK SWITCH, Stay", "TASK SWITCH, Switch"), class = "factor"), 
    aic = c(28901.0609423639, 28876.584417846, 28870.0889374339, 
    28862.7732527584, 28859.716837592, 28852.6732473908, 28851.1317635441, 
    28853.8500632933)), class = "data.frame", row.names = c(NA, 
-8L))

efficiency.math <- structure(list(variables = structure(c(2L, 1L, 5L, 4L, 3L, 6L
), .Label = c("Con, Box, Feature", "Demographics", "FILTER", 
"SAAT, Sustained", "Tap and Trace, Tap", "TASK SWITCH, Stay"), class = "factor"), 
    aic = c(28900.5294523709, 28885.7432348228, 28877.1589335409, 
    28872.248022988, 28868.3257096905, 28865.1849707033)), class = "data.frame", row.names = c(NA, 
-6L))

rw.math<- structure(list(variables = structure(c(2L, 1L, 3L, 4L, 5L), .Label = c("BOXED, Feature, 4", 
"Demographics", "SAAT, Impulsive", "Tap and Trace", "Tap and Trace, Tap"
), class = "factor"), aic = c(28896.4668953137, 28882.0804928958, 
28875.7128176706, 28873.9645461461, 28872.7298323499)), class = "data.frame", row.names = c(NA, 
-5L))

colourCount = length(unique(efficiency.math$variables))
getPalette = colorRampPalette(brewer.pal(9, "Set1"))
efficiency.math%>%
  mutate(name = fct_reorder(variables, desc(aic)))%>%
  ggplot(aes(x = name, y = aic - 28850, fill = name))+
  geom_col()+
  coord_flip()+
  cleanup+
    theme(strip.text.x = element_text(size=7, angle=0),
          strip.background = element_rect(colour="white", fill="white"))+
  scale_fill_manual(values = getPalette(colourCount))+
  theme(legend.position="right")+
  theme(plot.title = element_text(hjust = 0))+
  #labs(x = "Cognitive Measures (Efficiency/Consistency)")+
  labs(y = "AIC + 28850")+
  ggtitle("3b: Math, Eff/Con Model")+
  guides(fill = FALSE)+
  set_theme(title.size = .6)+
  theme(axis.text.x = element_text(size = 5),
        axis.text.y = element_text(size = 6),
        axis.title.x = element_text(size = 8),
        axis.title.y = element_blank())+
  cleanup

colourCount = length(unique(final.ela.17.18.rem$variables))
getPalette = colorRampPalette(brewer.pal(6, "Set1"))

efficiency.english%>%
  mutate(name = fct_reorder(variables, desc(aic)))%>%
  ggplot(aes(x = name, y = aic - 28825, fill = variables))+
  geom_col()+
  coord_flip()+
  cleanup+
    theme(strip.text.x = element_text(size=7, angle=0),
          strip.background = element_rect(colour="white", fill="white"))+
  theme(plot.title = element_text(hjust = 0))+
  scale_fill_manual(values = getPalette(colourCount))+
  theme(legend.position="right")+
  labs(y = "AIC + 28825")+
  ggtitle("3c: English, Eff/Con Model")+
  guides(fill=FALSE)+
  set_theme(title.size = .6)+
  theme(axis.text.x = element_text(size = 5),
        axis.text.y = element_text(size = 6),
        axis.title.x = element_text(size = 8),
        axis.title.y = element_blank())+
    cleanup

colourCount = length(unique(rw.math$variables))
getPalette = colorRampPalette(brewer.pal(9, "Set1"))
rw.math%>%
  mutate(name = fct_reorder(variables, desc(aic)))%>%
  ggplot(aes(x = name, y = aic - 28860, fill= variables))+
  geom_col()+
  coord_flip()+
  scale_fill_brewer(palette="Set2")+
  labs(x = "Cognitive Measures")+
  labs(y = "AIC + 28,860")+
  ggtitle("3d: Math, RW Model")+
  guides(fill = FALSE)+
   set_theme(title.size = .6)+
  theme(axis.text.x = element_text(size = 5),
        axis.text.y = element_text(size = 6),
        axis.title.x = element_text(size = 8),
        axis.title.y = element_text(size = 8))+
  cleanup

【问题讨论】:

    标签: r ggplot2 modeling colorbrewer


    【解决方案1】:

    我并没有立即清楚与编程相关的实际问题是什么,但如果我收集正确,它是关于如何在一系列图中为因子变量获得一致的颜色,对吗?

    附带说明的是,很难找到 26 种非常可区分的颜色,但它们在 Polychrome 包中确实有一个字母调色板。

    主要是如何在绘图中设置填充/颜色比例,在伪代码中如下所示:

    scale_fill_manual(
          values = setNames(a_colour_vector, all_factor_levels),
          breaks = all_ordered_factor_levels_to_be_displayed,
          limits = all_ordered_factor_levels_to_be_displayed)
        )
    

    下面是您提供的向量示例:

    library(Polychrome)
    library(ggplot2)
    library(patchwork)
    
    # Data from question
    response_window <- c("T", "A", "G", "C")
    efficiency <- c("R", "A", "M", "T", "E", "L")
    consistency <- c("S", "M", "W", "A", "L", "F")
    psychometric_threshold <- c("S", "C", "H", "I", "D")
    
    # Format data as data.frame
    df <- rbind.data.frame(
      cbind(name = "response_window", var = response_window),
      cbind(name = "efficiency", var = efficiency),
      cbind(name = "consistency", var = consistency),
      cbind(name = "psychometric_threshold", var = psychometric_threshold)
    )
    
    # Generate some value to substitute for AIC
    df$value <- rpois(nrow(df), 5)
    
    # Some ordering of the variables, for example random
    # in real case probably AIC related ordering
    unique_var <- unique(df$var)
    df$var <- factor(df$var, levels = sample(unique_var))
    
    # Loop over name, create plot for each name
    plotlist <- lapply(split(df, df$name), function(dat) {
      ggplot(dat, aes(var, value, fill = var)) +
        geom_col(position = "dodge") +
        scale_fill_manual(
          values = setNames(alphabet.colors(), LETTERS),
          breaks = levels(dat$var),
          limits = levels(dat$var)
        ) +
        coord_flip() +
        ggtitle(dat$name[1])
    })
    
    # Combine plots for visualisation purposes
    plotlist[[1]] + plotlist[[2]] + plotlist[[3]] + plotlist[[4]] + plot_layout(guides = "collect")
    

    reprex package (v0.3.0) 于 2019 年 12 月 1 日创建

    绘图的确切外观可能无法反映您的用例,但您可以看到绘图的颜色是一致的。

    编辑:更新问题后,我的建议是执行以下操作:

    # Put data in list
    data_list <- list(
      efficiency_math = efficiency.math,
      efficiency_english = efficiency.english,
      rw_math = rw.math
    )
    
    # Edit some metadata
    all_levels <- unique(unlist(lapply(data_list, `[[`, "variables")))
    colours <- Polychrome::kelly.colors(length(all_levels))
    colours <- setNames(colours, all_levels)
    titles <- c("3b: Math, Eff/Con Model", "3c: English, Eff/Con Model", "Cognitive Measures")
    
    # Loop over the data
    plot_list <- mapply(function(df, title) {
      df$name <- fct_reorder(df$name, desc(df$aic))
    
      ggplot(df, aes(name, aic, fill = name)) +
        geom_col(colour = "black") +
        scale_fill_manual(
          values = colours
        ) +
        scale_y_continuous(limits = range(df$aic),
                           oob = function(x, ...) x,
                           expand = c(0.2, 0)) +
        coord_flip() +
        theme_classic() +
        ggtitle(title)
    }, df = data_list, title = titles, SIMPLIFY = FALSE)
    

    产生以下结果:

    plot_list[[1]]
    

    我使用调整后的 y 比例而不是“AIC - 28850”方法的原因是,如果值已经在原始 AIC 中,您可以让绘图的观察者不用考虑偏移量的心算空间。它还让您不必为每个地块考虑适当的偏移量。

    这是一个包含偏移量参数的变体:

    plot_list <- mapply(
      function(df, title, offset) {
        df$name <- fct_reorder(df$name, desc(df$aic))
    
        ggplot(df, aes(name, aic - offset, fill = name)) +
          geom_col(colour = "black") +
          scale_fill_manual(
            values = colours
          ) +
          scale_y_continuous(name = paste0("AIC + ", offset)) +
          coord_flip() +
          theme_classic() +
          ggtitle(title)
      }, 
      df = data_list, 
      title = titles, 
      offset = c(28850, 28825, 28860),
      SIMPLIFY = FALSE
    )
    

    绘图仍然是可编辑的,因此您可以提供特定于绘图的详细信息,如下所示:

    plot_list[[3]] + labs(x = "Cognitive Measures")
    

    【讨论】:

    • 是的,这太完美了! “一系列情节中因子变量的一致着色” - 这更简洁......不知道如何表达。很高兴了解彩色包装。谢谢!
    • 作为后续问题:如果不将变量和观察结果组合到同一个数据集中,就无法执行此操作?
    • 抱歉--我现在看到我的问题在哪里可以更清楚,并编辑了我的问题以反映这一点。上述方法确实有效,但问题是总 AIC 落在 30,000 左右,因此图表中的最终任务变量 AIC 值相对难以区分。在应用拼凑包后,也许有一种方法可以个性化图表;或者也许对我的问题的编辑可能会更好地了解图表之间的差异。
    • 对,如果我理解正确的话; (1) 您希望以编程方式得出图,而不必先组合所有数据; (2)您想要一个合理的 AIC 轴,在较大的数字周围变化相对较小,(3)获得每个图的输出?可以做到,但只是想在我对提议的答案进行一些无意义的编辑之前确定一下。
    • 1) 是的,这是正确的。 2)理想情况下,我希望能够在给定 AIC 输出的情况下更改单个图(例如,我可以将“y = value - 29000”之类的内容放入 ggplot(aes()),但实际上,我希望能够每个情节单独执行此操作。3)不确定第三个与 2 有何不同,但也许一些额外的信息可能会有所帮助:我可以在 Rmarkdown 中使用 fig.hold 和 fig.align 命令将所有内容收集到一个图中,所以它是很好,输出是五个单独的图(很高兴知道拼凑包和“收集”功能)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    相关资源
    最近更新 更多