ggplot2:将因子变量传递给 facet_wrap
ggplot2: pass factor variable to facet_wrap
我正在尝试替换逐行脚本以生成带有函数的 ggplot2 图形 - 但已经摆脱了 facet_wrap
为了概括这个问题,我创建了这个玩具数据集 - 它绘制了两个主题(“ID”)随时间变化的值
day <- c(0, 3, 5, 7, 9, 14, 0, 3, 5, 7, 9, 14)
value <- c(0.0, 3.6, 6.7, 7.6, 8.7, 0.0, 0.0, 1.0, 1.2, 8.3, 1.2, 0.0)
ID <- as.factor(c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2))
df <- data.frame(ID, day, value)
通过以下脚本方法,我可以生成当天价值的线图 - 两个主题的分面
ggplot(df, aes(day, value)) + geom_line() + facet_wrap(~ID)
然后我尝试通过使用以下代码创建然后调用一个函数来做到这一点:
fun <- function(data, x, y, fac){
p <- ggplot(df, aes(x, y)) + geom_line()
p + facet_wrap(~fac)
}
fun(df, day, value, ID)
但是我得到以下错误:
Error: At least one layer must contain all faceting variables: `fac`.
* Plot is missing `fac`
* Layer 1 is missing `fac`
有趣的是,如果我将 "ID" 硬编码到函数中,一切正常 - 我什至不必传递分面变量
fun <- function(data, x, y){
p <- ggplot(df, aes(x, y)) + geom_line()
p + facet_wrap(~ID)
}
fun(df, day, value)
但是这种方式破坏了创建函数的普遍化优势
如果有人能告诉我我做错了什么以及可能的解决方法,我将不胜感激
谢谢
PS。我已经检查了 StackExchange 上的答案,虽然有几个关于 facet_wrap 的问题有些相似,但要么我无法使用建议的解决方案,要么不理解它们
因为非标准评估以微妙的方式改变了作用域规则,你不能简单地将变量输入函数内的 aes()
或 vars()
调用(~ formula
符号包装 vars()
).您可以在此处找到对此问题的更详细处理:https://ggplot2.tidyverse.org/articles/ggplot2-in-packages.html
其中一个解决方案是将您的变量名包装到 {{...}}
中,这表明非标准评估应该与作为参数给出的任何表达式一起出现,而不是参数表达式的评估值。
library(ggplot2)
day <- c(0, 3, 5, 7, 9, 14, 0, 3, 5, 7, 9, 14)
value <- c(0.0, 3.6, 6.7, 7.6, 8.7, 0.0, 0.0, 1.0, 1.2, 8.3, 1.2, 0.0)
ID <- as.factor(c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2))
df <- data.frame(ID, day, value)
fun <- function(data, x, y, fac){
p <- ggplot(df, aes({{x}}, {{y}})) + geom_line()
p + facet_wrap(vars({{fac}}))
}
fun(df, day, value, ID)
由 reprex package (v0.3.0)
于 2020-05-27 创建
此外,请注意,您还应该将 x
和 y
变量括起来。它之前工作的唯一原因是因为 day
和 value
是全局环境中的变量(并且长度为 nrow(df)
)。以下 returns 如果 运行 在干净的环境中会出错:
library(ggplot2)
df <- data.frame(
ID = as.factor(c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2)),
day = c(0, 3, 5, 7, 9, 14, 0, 3, 5, 7, 9, 14),
value = c(0.0, 3.6, 6.7, 7.6, 8.7, 0.0, 0.0, 1.0, 1.2, 8.3, 1.2, 0.0)
)
fun <- function(data, x, y, fac){
p <- ggplot(df, aes(x, y)) + geom_line()
p + facet_wrap(vars({{fac}}))
}
fun(df, day, value, ID)
#> Error in FUN(X[[i]], ...): object 'day' not found
由 reprex package (v0.3.0)
于 2020-05-27 创建
我正在尝试替换逐行脚本以生成带有函数的 ggplot2 图形 - 但已经摆脱了 facet_wrap
为了概括这个问题,我创建了这个玩具数据集 - 它绘制了两个主题(“ID”)随时间变化的值
day <- c(0, 3, 5, 7, 9, 14, 0, 3, 5, 7, 9, 14)
value <- c(0.0, 3.6, 6.7, 7.6, 8.7, 0.0, 0.0, 1.0, 1.2, 8.3, 1.2, 0.0)
ID <- as.factor(c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2))
df <- data.frame(ID, day, value)
通过以下脚本方法,我可以生成当天价值的线图 - 两个主题的分面
ggplot(df, aes(day, value)) + geom_line() + facet_wrap(~ID)
然后我尝试通过使用以下代码创建然后调用一个函数来做到这一点:
fun <- function(data, x, y, fac){
p <- ggplot(df, aes(x, y)) + geom_line()
p + facet_wrap(~fac)
}
fun(df, day, value, ID)
但是我得到以下错误:
Error: At least one layer must contain all faceting variables: `fac`.
* Plot is missing `fac`
* Layer 1 is missing `fac`
有趣的是,如果我将 "ID" 硬编码到函数中,一切正常 - 我什至不必传递分面变量
fun <- function(data, x, y){
p <- ggplot(df, aes(x, y)) + geom_line()
p + facet_wrap(~ID)
}
fun(df, day, value)
但是这种方式破坏了创建函数的普遍化优势
如果有人能告诉我我做错了什么以及可能的解决方法,我将不胜感激
谢谢
PS。我已经检查了 StackExchange 上的答案,虽然有几个关于 facet_wrap 的问题有些相似,但要么我无法使用建议的解决方案,要么不理解它们
因为非标准评估以微妙的方式改变了作用域规则,你不能简单地将变量输入函数内的 aes()
或 vars()
调用(~ formula
符号包装 vars()
).您可以在此处找到对此问题的更详细处理:https://ggplot2.tidyverse.org/articles/ggplot2-in-packages.html
其中一个解决方案是将您的变量名包装到 {{...}}
中,这表明非标准评估应该与作为参数给出的任何表达式一起出现,而不是参数表达式的评估值。
library(ggplot2)
day <- c(0, 3, 5, 7, 9, 14, 0, 3, 5, 7, 9, 14)
value <- c(0.0, 3.6, 6.7, 7.6, 8.7, 0.0, 0.0, 1.0, 1.2, 8.3, 1.2, 0.0)
ID <- as.factor(c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2))
df <- data.frame(ID, day, value)
fun <- function(data, x, y, fac){
p <- ggplot(df, aes({{x}}, {{y}})) + geom_line()
p + facet_wrap(vars({{fac}}))
}
fun(df, day, value, ID)
由 reprex package (v0.3.0)
于 2020-05-27 创建此外,请注意,您还应该将 x
和 y
变量括起来。它之前工作的唯一原因是因为 day
和 value
是全局环境中的变量(并且长度为 nrow(df)
)。以下 returns 如果 运行 在干净的环境中会出错:
library(ggplot2)
df <- data.frame(
ID = as.factor(c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2)),
day = c(0, 3, 5, 7, 9, 14, 0, 3, 5, 7, 9, 14),
value = c(0.0, 3.6, 6.7, 7.6, 8.7, 0.0, 0.0, 1.0, 1.2, 8.3, 1.2, 0.0)
)
fun <- function(data, x, y, fac){
p <- ggplot(df, aes(x, y)) + geom_line()
p + facet_wrap(vars({{fac}}))
}
fun(df, day, value, ID)
#> Error in FUN(X[[i]], ...): object 'day' not found
由 reprex package (v0.3.0)
于 2020-05-27 创建