【问题标题】:Changing legend order in ggplot within a function在函数中更改 ggplot 中的图例顺序
【发布时间】:2019-12-26 20:52:12
【问题描述】:

我想在函数中绘制一个数据框。图例应以特定方式排序。为了在我的示例中保持简单,我只是颠倒了顺序。我实际上想选择一个特定的行并将其推到图例的最后一个位置。

顺便说一句,我正在创建一个新的 R 包,如果这有任何相关性的话。

在函数外绘图

attach(iris)
library(ggplot2)


# This is a normal plot
p <- ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length, fill = Species) ) +
  geom_bar( stat = "identity")
p

# This is a plot with reversed legend
iris$Species <- factor(iris$Species, levels = rev(levels(iris$Species)))
p <- ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length, fill = Species) ) +
  geom_bar( stat = "identity")
p

在函数内部绘图

最简单的方法就是使用变量,这显然行不通

f1 <- function(myvariable) {
  iris$myvariable <- factor(iris$myvariable, levels = rev(levels(iris$myvariable)))
  p <- ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length, fill = Species) ) +
    geom_bar( stat = "identity")
  p
}
f1("Species")

 #> Error in `$<-.data.frame`(`*tmp*`, myvariable, value = integer(0)) : 
  replacement has 0 rows, data has 150 

我尝试使用 quasiquotation,但这种方法只能让我绘制数据框。我还不能调换顺序。

library(rlang)
# Only plotting works
f2 <- function(myvariable) {
  v1 <- ensym(myvariable)
  p <- ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length, fill = eval(expr(`$`(iris, !!v1))))) +
    geom_bar( stat = "identity")
  p
}
f2("Species")

# This crashes
f3 <- function(myvariable) {
  v1 <- ensym(myvariable)
  expr(`$`(iris, !!v1)) <- factor(expr(`$`(iris, !!v1)), levels = rev(levels(expr(`$`(iris, !!v1)))))
  p <- ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length, fill = eval(expr(`$`(iris, !!v1))))) +
    geom_bar( stat = "identity")
  p
}
f3("Species")

#> Error in `*tmp*`$!!v1 : invalid subscript type 'language'

所以主要问题是,我不能使用准引用来分配东西。

【问题讨论】:

    标签: r ggplot2 rlang quasiquotes


    【解决方案1】:

    有几点:

    • 您可以使用[[ 而不是$ 以编程方式访问数据框列。
    • 您可以在 R CMD 检查期间使用ggplot 的aes_string 最小化注释(因为您提到您正在做一个包)。
    • 您可以使用包forcats 中的fct_relevel 将因子级别“发送”到末尾。

    翻译为:

    f <- function(df, var) {
      lev <- levels(df[[var]])
      df[[var]] <- forcats::fct_relevel(df[[var]], lev[1L], after = length(lev) - 1L)
    
      ggplot(df, aes_string(x = "Sepal.Width", y = "Sepal.Length", fill = var)) +
        geom_bar(stat = "identity")
    }
    
    f(iris, "Species")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 2022-08-15
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 2020-12-02
      • 2020-01-30
      相关资源
      最近更新 更多