Mik*_*ike 14 r ggplot2 dplyr tidyeval rlang
library(dplyr) #Devel version, soon-to-be-released 0.6.0
library(tidyr)
library(ggplot2)
library(forcats) #for gss_cat data
Run Code Online (Sandbox Code Playgroud)
我正在尝试编写一个函数,它结合了即将发布的dplyrdevel版本的quosures tidyr::gather和ggplot2.到目前为止它似乎可以使用tidyr,但我在绘图方面遇到了麻烦.
以下功能似乎适用于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))
}
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚如何让情节发挥作用.我试着用!!gath用ggplot2,但没有奏效.
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))
}
Run Code Online (Sandbox Code Playgroud)
Mik*_*ike 11
为了完成这项工作,我不得不使用dplyr::quo_name将quosure更改为字符串.我还必须使用ggplot2::aes_string,这也要求所有输入都是字符串,因此引用"".
GatherFun <- function(gath){
gath <- enquo(gath)
gathN <- quo_name(gath)
gss_cat %>%
select(relig, marital, race, partyid) %>%
gather(key, value, -!!gath) %>%
count(!!gath, key, value) %>%
mutate(perc = round(n/sum(n), 2)) %>%
ggplot() +
geom_col(aes_string(x = "value", y = "perc", fill = gathN)) +
facet_wrap(~key, scales = "free") +
geom_text(aes_string(x = "value", y = "perc", label = "perc", group = gathN),
position = position_stack(vjust = .05))
}
Run Code Online (Sandbox Code Playgroud)
我觉得主要的问题是ggplot,当它试图评估时会贪婪,!!gath并且!(!gath)抛出一个not(gath)没有意义的错误.当我尝试使用时,我已经出现了这个问题,!!所以我有点厌倦了以糖的形式使用它.
如果更准确的人可以正确识别问题,那肯定会有所帮助.
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)
)
}
Run Code Online (Sandbox Code Playgroud)
你在问题中写的函数调用似乎有一些错误.正确间隔代码将有助于避免这种情况.
您也没有使用该rlang呼叫,我只是没有dplyr安装最新版本.
编辑一些想法使用一个更简单的mtcars例子:
Tbh我很不确定这里发生了什么,但我想这与ggplot2现在相对较老的事实有关,并且设计略有不同?踏入aes同debug,我们发现类似的结构
structure(list(x = mpg, y = eval(rlang::UQE(var))), .Names = c("x",
"y"), class = "uneval")
Run Code Online (Sandbox Code Playgroud)
(这不会通过解释器运行,但大致是结构的样子).我认为这说明了为什么eval这里需要调用,o/w ggplot试图映射rlang::UQE(var)到y审美并报告它不知道如何处理类的东西name.eval例如,将名称评估为cyl,然后美学可以正常映射.
我想dplyr动词没有这个额外的映射步骤,其中参数以相同的方式被操纵到某个中间结构,所以我们没有这个问题.
另外,当我说你不必使用这个rlang电话时,那是因为我假设这个功能被重新导出到新dplyr版本中.由于我之前提到的整体!!(...)或!(!(...))事物,我更喜欢使用rlang::"!!",或者rlang::UQE(我认为这完全相同).
大多数情况都是猜测,如果有人能纠正我的任何错误,我将不胜感激.