【问题标题】:How to manually set colours *conditionally* in aes() AND local geom_xxx() in ggplot?如何在 ggplot 中的 aes() 和本地 geom_xxx() 中手动设置颜色*有条件*?
【发布时间】:2020-01-12 11:18:12
【问题描述】:

我正在尝试创建一个函数,该函数可以采用单个组或多个组,同时使用单个 colour 参数。但是,在全局(aes())和本地(geom_smooth())中指定colour 似乎存在问题。看起来aes() 不接受colour=NULL 或者只是留空colour=

无组情节(作品)

scatterfunction <- function (Data=mtcars,Predictor=mtcars$wt,Response=mtcars$mpg,what.Colour="purple") {
  library(ggplot2)
  ggplot(Data,aes(x=Predictor,y=Response)) +
    geom_smooth(method="lm",colour=what.Colour)
}
scatterfunction()

与团体一起策划(作品)

groupscatterfunction <- function (Data=mtcars,Predictor=mtcars$wt,Response=mtcars$mpg,Group.variable=factor(mtcars$cyl),what.Colour=c("purple", "yellow", "brown")) {
  library(ggplot2)
  ggplot(Data,aes(x=Predictor,y=Response,colour=Group.variable)) +
    geom_smooth(method="lm") +
    scale_color_manual(values=what.Colour)
}
groupscatterfunction()

不带组的情节,有条件的(has.Groups=F 时有效)

conditionalscatterfunction <- function (Data=mtcars,Predictor=mtcars$wt,Response=mtcars$mpg,Group.variable=factor(mtcars$cyl),has.Groups=F,what.Colour="purple") {
  library(ggplot2)
  ggplot(Data,aes(x=Predictor,y=Response,colour= if(has.Groups==T) {Group.variable})) +
    geom_smooth(method="lm",colour= if(has.Groups==F){what.Colour}) +
    if (has.Groups==T) {scale_color_manual(values=what.Colour)}
}
conditionalscatterfunction()

按组绘制,有条件(has.Groups=T 时不起作用)

conditionalscatterfunction(Data = mtcars,
                           Predictor = mtcars$wt,
                           Response = mtcars$mpg,
                           has.Groups = TRUE,
                           Group.variable = factor(mtcars$cyl),
                           what.Colour = c("purple", "yellow", "brown"))

Error: Aesthetics must be either length 1 or the same as the data (80): colour

使用替代 switch() 语句以前对我有用,但在这里不行:

conditionalscatterfunction <- function (Data=mtcars,Predictor=mtcars$wt,Response=mtcars$mpg,Group.variable=factor(mtcars$cyl),has.Groups=T,what.Colour=c("purple", "yellow", "brown")) {
  library(ggplot2)
  ggplot(Data,aes(x=Predictor,y=Response,colour= switch(has.Groups, Group.variable))) +
    geom_smooth(method="lm",colour= if(has.Groups==F){what.Colour}) +
    if (has.Groups==T) {scale_color_manual(values=what.Colour)}
}
conditionalscatterfunction()

Error: Aesthetics must be either length 1 or the same as the data (80): colour

似乎只要我在aesthetics() 中添加“colour=”语句,无论是留空还是= NULL,都会出现此错误。那么当没有显式调用时它的默认值是什么?

我宁愿避免再次重复整个调用,因为geom_points()geom_shape() 等也有这个问题,我需要为每个元素组合重复它...

问题:我该如何解决这个问题?

【问题讨论】:

  • 刚刚回复你的第一段,你试过colour = NA而不是colour = NULL吗?
  • 很有趣,所以它确实像aes(colour=NA) 一样独立工作,但当包含在switch()ifelse() 语句中时则不能...也许aes() 只是不能接受@987654353 @ 或 ifelse() 声明?
  • 如果您首先使用dplyr 进行数据预处理并使用if-else 条件添加另一个color 列应该会更容易。然后您可以引用@987654358 中的color 列@.
  • @YifuYan 我不知道这是否是你想要我做的,但我在函数中添加了这个调用:ifelse(has.Groups==T,(mtcars$colour.col = Group.variable),(mtcars$colour.col = what.Colour))。然后我换成了aes(colour=mtcars$colour.col)。如果我删除 geom_smooth 中的 colour= 参数,则有效,但否则无效...我这样做对吗?

标签: r ggplot2 colors aesthetics


【解决方案1】:

有很多方法可以给这只猫剥皮,但一个简单的方法是使用if {} else {} 预先定义geom_smooth。例如:

conditionalscatterfunction <- function (Data, Predictor, Response, Group.variable, col = c("purple", "yellow", "brown")) {
  require(ggplot2)

  if (missing(Group.variable)) {
    smooth <- geom_smooth(method = "lm", color = col[1])
  } else {
    smooth <- geom_smooth(aes(color = {{Group.variable}}), method = "lm")
  }

  ggplot(Data, aes(x = {{Predictor}},y = {{Response}})) +
    smooth +
    scale_color_manual(values = col)
}

conditionalscatterfunction(mtcars, wt, mpg)
conditionalscatterfunction(mtcars, wt, mpg, factor(cyl))

两者都可以正常工作。

【讨论】:

  • 是的,很好,谢谢@Axeman。但是,正如我在帖子中提到的,我将在这里复制 geom_smooth 调用......难道没有办法在 geom_smooth 调用本身中使用 ifelse() 调用吗?否则,我需要对所有其他选项和组合重复此操作:geom_points()geom_jittergeom_shape()geom_line 等,这不尊重 DRY 原则,对吧?考虑一个额外的ifelse()has.points == TRUE 语句,这将需要 T 和 F 的每个颜色重复 2 个,导致单个调用有 4 个重复......或者我弄错了吗? :3
  • 你不能轻易做到这一点,因为当你定义组变量时,你不能在aes之外传递任何东西给color。传递NULL 会引发错误,传递NA 会使该行消失。
  • 我明白了。所以我的实际功能可能是超长的,但毕竟我可能别无选择......好吧,如果这是唯一的方法,那就行了! :)
  • 这取决于什么是有条件的。有些事情您可以更轻松地即时定义。参见例如stackoverflow.com/questions/22915337/…
猜你喜欢
  • 2013-08-16
  • 1970-01-01
  • 2016-02-08
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多