如何在 ggplot() 内部的 interaction(...) 参数中混合非标准和标准评估?
How to mix non-standard and standard evaluation in arguments to interaction(...) inside ggplot()?
我正在寻找一种使用 rlang
包在 dplyr
中使用 NSE 内部参数(在本例中为相交)的方法。
数据框:
df <- data.frame(time=as.factor(c(10,10,10,10,20,20,20,20,10,10,10,10,20,20,20,20)),
cost=as.factor(c(10,20,30,40,10,20,30,40,10,20,30,40,10,20,30,40)),
type=c("a","a","a","a","a","a","a","a","b","b","b","b","b","b","b","b"),
value=c(40,20,25,10,80,50,30,60,15,70,80,10,50,20,30,40))
## Set variables for NSE
a <- "time"
b <- "cost"
c <- "type"
d <- "value"
nse_a <- sym(a)
nse_b <- sym(b)
nse_c <- sym(c)
nse_d <- sym(d)
我可以在 SE 中正确绘制。
## Plot in SE
df %>% ggplot(aes(x=cost, y=value, group=interaction(time,type), color=time, linetype=type)) + geom_line(size=1.2)
但是,当我使用NSE时,出现错误:
## Plot in NSE
df %>% ggplot(aes_(x=nse_b, y=nse_d, group=interaction(nse_a,nse_c), color=nse_a, linetype=nse_c)) + geom_line(size=1.2)
Error: unique.default(x, nmax = nmax)
unique() applies only to vectors
如果我删除 group=intersection(...)
,它会起作用。我想原因可能是在 aes_
.
内的嵌套参数 'intersect(...)' 中使用了 NSE
你有什么解决办法可以避免这个错误吗?
我搜索了类似的主题并尝试应用一些示例,例如 !!nse_a 取消引用,但没有成功。我是新手'NSE',对它的操作方式还不是很了解
Base R 的 interaction
不适用于 rlang
,通常仅适用于 tidyverse。 (编辑:但请参阅 GGamba 的回答,其中显示了如何使用 !!
将 NSE 参数传递给标准函数。)
几乎可以肯定,最简单的解决方案是自己创建交互变量。
df$mygroup <- interaction(df$time, df$type)
现在在 ggplot
调用中使用 mygroup
。
这样做可以避免 NSE 地狱。
您只能将带引号的参数传递给 aes_()
,因此 interaction
必须带引号,但它本身需要不带引号的参数(这里的术语不是很清楚,如有混淆请见谅)
library(rlang)
library(ggplot2)
interact <- quo(interaction(!!nse_a, !!nse_c))
df %>%
ggplot(aes_(x=nse_b,
y=nse_d,
group=interact,
color=nse_a,
linetype=nse_c)) +
geom_line(size=1.2)
# or equally
df %>%
ggplot(aes_(x=nse_b,
y=nse_d,
group=quo(interaction(!!nse_a, !!nse_c)),
color=nse_a,
linetype=nse_c)) +
geom_line(size=1.2)
由 reprex package (v0.2.0) 创建于 2018-05-09。
我正在寻找一种使用 rlang
包在 dplyr
中使用 NSE 内部参数(在本例中为相交)的方法。
数据框:
df <- data.frame(time=as.factor(c(10,10,10,10,20,20,20,20,10,10,10,10,20,20,20,20)),
cost=as.factor(c(10,20,30,40,10,20,30,40,10,20,30,40,10,20,30,40)),
type=c("a","a","a","a","a","a","a","a","b","b","b","b","b","b","b","b"),
value=c(40,20,25,10,80,50,30,60,15,70,80,10,50,20,30,40))
## Set variables for NSE
a <- "time"
b <- "cost"
c <- "type"
d <- "value"
nse_a <- sym(a)
nse_b <- sym(b)
nse_c <- sym(c)
nse_d <- sym(d)
我可以在 SE 中正确绘制。
## Plot in SE
df %>% ggplot(aes(x=cost, y=value, group=interaction(time,type), color=time, linetype=type)) + geom_line(size=1.2)
但是,当我使用NSE时,出现错误:
## Plot in NSE
df %>% ggplot(aes_(x=nse_b, y=nse_d, group=interaction(nse_a,nse_c), color=nse_a, linetype=nse_c)) + geom_line(size=1.2)
Error: unique.default(x, nmax = nmax)
unique() applies only to vectors
如果我删除 group=intersection(...)
,它会起作用。我想原因可能是在 aes_
.
你有什么解决办法可以避免这个错误吗?
我搜索了类似的主题并尝试应用一些示例,例如 !!nse_a 取消引用,但没有成功。我是新手'NSE',对它的操作方式还不是很了解
Base R 的 interaction
不适用于 rlang
,通常仅适用于 tidyverse。 (编辑:但请参阅 GGamba 的回答,其中显示了如何使用 !!
将 NSE 参数传递给标准函数。)
几乎可以肯定,最简单的解决方案是自己创建交互变量。
df$mygroup <- interaction(df$time, df$type)
现在在 ggplot
调用中使用 mygroup
。
这样做可以避免 NSE 地狱。
您只能将带引号的参数传递给 aes_()
,因此 interaction
必须带引号,但它本身需要不带引号的参数(这里的术语不是很清楚,如有混淆请见谅)
library(rlang)
library(ggplot2)
interact <- quo(interaction(!!nse_a, !!nse_c))
df %>%
ggplot(aes_(x=nse_b,
y=nse_d,
group=interact,
color=nse_a,
linetype=nse_c)) +
geom_line(size=1.2)
# or equally
df %>%
ggplot(aes_(x=nse_b,
y=nse_d,
group=quo(interaction(!!nse_a, !!nse_c)),
color=nse_a,
linetype=nse_c)) +
geom_line(size=1.2)
由 reprex package (v0.2.0) 创建于 2018-05-09。