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)值<-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,2))df<-data.frame(ID,day,value)
使用以下脚本编制方法,我可以生成当天值的线图-涉及两个主题
ggplot(df,aes(day,value))+ geom_line()+ facet_wrap(〜ID)
然后我尝试通过创建并使用以下代码调用函数来做到这一点:
fun<-函数(数据,x,y,fac){p<-ggplot(df,aes(x,y))+ geom_line()p + facet_wrap(〜fac)}乐趣(df,日期,值,ID)
但是出现以下错误:
错误:至少一层必须包含所有构面变量:fac.*情节缺少`fac`*第1层缺少`fac`
有趣的是,如果我将"ID"硬编码到函数中,则一切正常-甚至不必传递构面变量
fun<-函数(data,x,y){p<-ggplot(df,aes(x,y))+ geom_line()p + facet_wrap(〜ID)}乐趣(df,日期,值)
但是这种失败破坏了创建函数的普遍意义
如果有人能告诉我我做错了什么以及可能的解决方法,我将不胜感激
谢谢
PS.我已经在StackExchange上做了一个答案的检查,尽管关于facet_wrap有一些类似的问题,但是我无法获得建议的解决方案,或者无法理解
由于非标准评估会以微妙的方式更改作用域规则,因此您不能简单地将变量输入 aes()
或函数内的vars()
调用(〜公式
表示法包装 vars()
).您可以在这里找到有关此问题的更详细的处理方法:(v0.3.0)创建于2020-05-27 sup>
此外,请注意,您还应该将 x
和 y
变量放在双括号中.它之前起作用的唯一原因是因为 day
和 value
是全局环境中的变量(长度为 nrow(df)
).如果在干净的环境中运行,以下内容将返回错误:
库(ggplot2)df<-data.frame(ID = as.factor(c(1,1,1,1,1,1,2,2,2,2,2,2,2)),天= c(0,3,5,7,9,14,14,0,3,5,7,9,14),值= 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))有趣的<-函数(数据,x,y,fac){p<-ggplot(df,aes(x,y))+ geom_line()p + facet_wrap(vars({{fac}}))}乐趣(df,日期,值,ID)#>FUN(X [[i]],...)中的错误:找不到对象'day'
由 reprex软件包(v0.3.0)创建于2020-05-27 sup>
i am trying to replace line-by-line scripting to produce ggplot2 graphics with functions - but have come unstuck with facet_wrap
To generalise the problem, I have created this toy dataset - which plots a value over time for two subjects ("IDs)
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)
With the following scripting approach, i can produce line plots of the value for the day - facetted on the two subjects
ggplot(df, aes(day, value)) + geom_line() + facet_wrap(~ID)
I then try to do this by creating and then calling a function using this code:
fun <- function(data, x, y, fac){
p <- ggplot(df, aes(x, y)) + geom_line()
p + facet_wrap(~fac)
}
fun(df, day, value, ID)
But I get the following error:
Error: At least one layer must contain all faceting variables: `fac`.
* Plot is missing `fac`
* Layer 1 is missing `fac`
Interesting, if I hardcode "ID" into the function, everything works - and I don't even have to pass a faceting variables
fun <- function(data, x, y){
p <- ggplot(df, aes(x, y)) + geom_line()
p + facet_wrap(~ID)
}
fun(df, day, value)
But this sort of defeats the generalising benefit of creating a function
I would be grateful if someone could tell me what i am doing wrong and what might be the work-around
Thanks
PS. I have done a check for an answer on StackExchange, and although there are several somewhat similar questions about facet_wrap, either I could not get the suggested solutions to work, or else did not understand them
Because non-standard evaluation changes the scoping rules in subtle ways, you cannot simply feed variables into aes()
or vars()
calls within functions (the ~ formula
notation wraps vars()
). A more detailed treatment of this problem you can find here: https://ggplot2.tidyverse.org/articles/ggplot2-in-packages.html
One of the solutions is to wrap you variable names into {{...}}
, which signals that the non standard evaluation should occur with whatever expression is given as the argument, instead of the evaluated value of the argument expression.
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)
Created on 2020-05-27 by the reprex package (v0.3.0)
Also, note that you should also double bracket the x
and y
variables. The only reason that it worked before was because the day
and value
were variables in the global environment (and of the length nrow(df)
). The following returns an error if run in a clean environment:
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
Created on 2020-05-27 by the reprex package (v0.3.0)
这篇关于ggplot2:将因子变量传递给facet_wrap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!