library(dplyr) #Devel version, soon-to-be-released 0.6.0
library(tidyr)
library(ggplot2)
library(forcats) #for gss_cat data
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.
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))
}
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))
}
In order to make this work I had to use
dplyr::quo_name
to change the quosure into a string. I also had to useggplot2::aes_string
, which also requires all the inputs to be strings, and therefore quoted with""
.I feel like the main problem is
ggplot
is greedy when it tries to evaluate!!gath
and does!(!gath)
, throwing an error asnot(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.
There seems to be a few mistakes in the function call you wrote in the question. properly spacing your code will help avoid that.
You also don't have you use the
rlang
call, I just don't have the newestdplyr
version installed.EDIT Some thoughts using a simpler
mtcars
example: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 intoaes
withdebug
, we find a structure similar to(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 maprlang::UQE(var)
to they
aesthetic and reports it doesn't know what to do with something of classname
.eval
evaluates the name to, say,cyl
, then the aesthetic can be mapped as normal.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.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 newdplyr
version. Because of the whole!!(...)
or!(!(...))
thing I mentioned earlier, I prefer to userlang::"!!"
, orrlang::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.
It's now possible to use tidy evaluation inside
aes
inggplot2 v3.0.0
. Thusaes_string
is no longer needed.I answered this question elsewhere recently (Use dplyr SE with ggplot2). Not sure how to mark duplicates so I will repeat here.
This bit of code should work in your example. Notice that all the hard-coded variables (value, perc, key) are quoted with a tilda while the quosure (gath) is used directly.