如何在带有tidyr和ggplot2的函数中使用dplyr的enquo和quo_name [英] How to use dplyr's enquo and quo_name in a function with tidyr and ggplot2
问题描述
library(dplyr) #Devel version, soon-to-be-released 0.6.0
library(tidyr)
library(ggplot2)
library(forcats) #for gss_cat data
我正在尝试编写一个函数,该函数将即将发布的dplyr
devel版本与tidyr::gather
和ggplot2
结合在一起.到目前为止,它似乎可以与tidyr
一起使用,但是我在绘制时遇到了麻烦.
I'm attempting to write a function that combines quosures from the soon-to-be-released dplyr
devel version together with tidyr::gather
and ggplot2
. So far it seems to work with tidyr
, but I'm having trouble with the plotting.
以下功能似乎可以与tidyr's gather
一起使用:
The below function seems to work with tidyr's gather
:
GatherFun<-function(gath){
gath<-enquo(gath)
gss_cat%>%select(relig,marital,race,partyid)%>%
gather(key,value,-!!gath)%>%
count(!!gath,key,value)%>%
mutate(perc=n/sum(n))
}
但是我不知道如何使这些图起作用.我尝试将!!gath
与ggplot2
结合使用,但是没有用.
But I can't figure out how to make the plots work. I tried using !!gath
with ggplot2
, but it didn't work.
GatherFun<-function(gath){
gath<-enquo(gath)
gss_cat%>%select(relig,marital,race,partyid)%>%
gather(key,value,-!!gath)%>%
count(!!gath,key,value)%>%
mutate(perc=n/sum(n))%>%
ggplot(aes(x=value,y=perc,fill=!!gath))+
geom_col()+
facet_wrap(~key, scales = "free") +
geom_text(aes(x = "value", y = "perc",
label = "perc", group = !!gath),
position = position_stack(vjust = .05))
}
推荐答案
我觉得主要问题是ggplot
在尝试评估!!gath
并执行!(!gath)
时过于贪婪,并抛出错误为not(gath)
没有任何意义.当我尝试使用!!
时,我遇到了很多问题,所以我有点厌倦以糖的形式使用它.
I feel like the main problem is ggplot
is greedy when it tries to evaluate !!gath
and does !(!gath)
, throwing an error as not(gath)
has no meaning. I've has this issue crop up a lot when I've tried to use !!
so I'm kinda weary about using it in its sugar form.
如果更精确的人能够正确识别问题,那肯定会有所帮助.
If someone more precise could correctly identify the problem it would definitely be helpful.
gather_func = function(gath) {
gath = enquo(gath)
gss_cat %>%
select(relig, marital, race, partyid) %>%
gather(key, value, -!!gath) %>%
count(!!gath, key, value) %>%
mutate(perc = round(n/sum(n), 2)) %>%
ggplot(aes(x = value, y = perc, fill = eval(rlang::`!!`(gath)))) +
geom_col() +
facet_wrap(~key, scales = "free") +
geom_text(
aes(
x = value,
y = perc,
label = perc,
group = eval(rlang::`!!`(gath))
),
position = position_stack(vjust = .05)
)
}
您在问题中编写的函数调用中似乎存在一些错误.正确地间隔代码可以避免这种情况.
There seems to be a few mistakes in the function call you wrote in the question. properly spacing your code will help avoid that.
您也没有使用rlang
呼叫,我只是没有安装最新的dplyr
版本.
You also don't have you use the rlang
call, I just don't have the newest dplyr
version installed.
编辑,使用更简单的mtcars
示例进行一些思考:
EDIT Some thoughts using a simpler mtcars
example:
我不太确定这是怎么回事,但我想这与ggplot2
现在相对较旧并且设计略有不同的事实有关吗?用debug
进入aes
,我们发现类似于
Tbh I'm quite unsure of what's going on here, but I imagine it's to do with the fact the ggplot2
is relatively old now and has a slightly different design? Stepping into aes
with debug
, we find a structure similar to
structure(list(x = mpg, y = eval(rlang::UQE(var))), .Names = c("x",
"y"), class = "uneval")
(这不会遍历解释器,但大致与结构类似).我认为这表明了为什么在这里需要eval
调用的原因,o/w ggplot试图将rlang::UQE(var)
映射到y
美学并且报告它不知道该如何处理类name
. eval
将名称评估为cyl
,则可以将外观映射为正常.
(This won't run through the interpreter but is roughly what the structure looks like). I think this shows why the eval
call is necessary here, o/w ggplot is trying to map rlang::UQE(var)
to the y
aesthetic and reports it doesn't know what to do with something of class name
. eval
evaluates the name to, say, cyl
, then the aesthetic can be mapped as normal.
我想象dplyr
动词没有这个额外的映射步骤,在该步骤中,参数以相同的方式被操纵到某种中间结构中,因此我们没有这个问题.
I imagine dplyr
verbs don't have this extra mapping step where the arguments are manipulated into some intermediate structure in the same way, so we don't have this issue.
另外,当我说您不必使用rlang
调用时,这是因为我假设此函数已重新导出到新的dplyr
版本中.由于我前面提到的整个!!(...)
或!(!(...))
内容,我更喜欢使用rlang::"!!"
或rlang::UQE
(我认为它们完全等效).
Also, when I said you don't have to use the rlang
call, it was because I assumed this function was re-exported into the new dplyr
version. Because of the whole !!(...)
or !(!(...))
thing I mentioned earlier, I prefer to use rlang::"!!"
, or rlang::UQE
(which are exactly equivalent I believe).
不过,其中大多数是猜测,如果有人可以纠正我犯错的任何内容,将不胜感激.
Most of this is speculation though and if someone could correct me on anything I've got wrong it would be appreciated.
这篇关于如何在带有tidyr和ggplot2的函数中使用dplyr的enquo和quo_name的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!