I am trying to create a function for creating lollipop plots using ggplot2
. I would like to pass all argument within ...
to aes()
within geom_point()
. However, I'd like to exclude the size
argument from passing onto aes()
within geom_segment()
(for obvious reasons if you look at the ouput of a()
below). Therefore I capture ...
using rlang::enquos()
instead of just passing it on as is. In function a()
where I pass the dots
to aes()
within ggplot()
this works without a problem. But in function b()
I get the error Can't use '!!!' at top level.
I am stuck at this point and would appreciate any input to solve this issue.
library(ggplot2)
data("mtcars")
d <- dplyr::count(mtcars, cyl, am)
a <- function(data, x, y, ...) {
x <- rlang::enquo(x)
y <- rlang::enquo(y)
dots <- rlang::enquos(...)
ggplot(data, aes(!!x, !!y, !!!dots)) +
geom_segment(aes(y = 0, xend = !!x, yend = !!y)) +
geom_point()
}
b <- function(data, x, y, ...) {
x <- rlang::enquo(x)
y <- rlang::enquo(y)
dots <- rlang::enquos(...)
segment_args <- dots[names(dots) != "size"]
ggplot(data, aes(!!x, !!y)) +
geom_segment(aes(y = 0, xend = !!x, yend = !!y, !!!segment_args)) +
geom_point(aes(!!!dots))
}
a(d, cyl, n, color = factor(am), size = am)
b(d, cyl, n, color = factor(am), size = am)
#> Error: Can't use `!!!` at top level.
Here is my sessionInfo()
:
R version 3.5.2 (2018-12-20)
Platform: x86_64-apple-darwin16.7.0 (64-bit)
Running under: macOS Sierra 10.12.1
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /usr/local/Cellar/openblas/0.3.5/lib/libopenblasp-r0.3.5.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods
[7] base
other attached packages:
[1] ggplot2_3.2.1
loaded via a namespace (and not attached):
[1] Rcpp_1.0.3 digest_0.6.18 withr_2.1.2
[4] assertthat_0.2.0 crayon_1.3.4 dplyr_0.8.3
[7] grid_3.5.2 R6_2.3.0 gtable_0.2.0
[10] magrittr_1.5 scales_1.0.0 pillar_1.4.2
[13] rlang_0.4.2 lazyeval_0.2.1 rstudioapi_0.10
[16] labeling_0.3 tools_3.5.2 glue_1.3.0
[19] purrr_0.3.3 munsell_0.5.0 compiler_3.5.2
[22] pkgconfig_2.0.2 colorspace_1.4-0 tidyselect_0.2.5
[25] tibble_2.1.3
Apparently this is a known issue of aes()
as you can verify here. A workaround is this:
b <- function(data, x, y, ...) {
x <- rlang::enquo(x)
y <- rlang::enquo(y)
dots <- rlang::enquos(...)
segment_args <- dots[names(dots) != "size"]
ggplot(data, aes(!!x, !!y)) +
geom_segment(aes(, y = 0, xend = !!x, yend = !!y, !!!segment_args)) +
geom_point(aes(, , !!!dots))
}
Notice the single comma in geom_segment()
and the double comma in geom_point()
.