在函数内更改ggplot中的图例顺序
Changing legend order in ggplot within a function
我想在函数中绘制数据框。图例应以特定方式排序。在我的示例中为了简单起见,我只是颠倒了顺序。我实际上想要 select 一个特定的行并将其推到图例的最后一个位置。
顺便说一句,我正在创建一个新的 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
我尝试使用准引用,但这种方法只能让我绘制数据框。我还不能撤单。
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'
所以主要的问题是,我不能使用准引用来赋值。
几件事:
- 您可以使用
[[
而不是 $
以编程方式访问数据框列。
- 您可以使用
ggplot
的 aes_string
在 R CMD 检查期间最小化注释(因为您提到您正在做一个包)。
- 您可以 "send" 一个因素水平到最后
fct_relevel
来自包 forcats
.
转换为:
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")
我想在函数中绘制数据框。图例应以特定方式排序。在我的示例中为了简单起见,我只是颠倒了顺序。我实际上想要 select 一个特定的行并将其推到图例的最后一个位置。
顺便说一句,我正在创建一个新的 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
我尝试使用准引用,但这种方法只能让我绘制数据框。我还不能撤单。
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'
所以主要的问题是,我不能使用准引用来赋值。
几件事:
- 您可以使用
[[
而不是$
以编程方式访问数据框列。 - 您可以使用
ggplot
的aes_string
在 R CMD 检查期间最小化注释(因为您提到您正在做一个包)。 - 您可以 "send" 一个因素水平到最后
fct_relevel
来自包forcats
.
转换为:
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")