Skip to content

Instantly share code, notes, and snippets.

@JonasMoss
Last active March 19, 2018 08:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JonasMoss/051c2e08672947d554062616babd1746 to your computer and use it in GitHub Desktop.
Save JonasMoss/051c2e08672947d554062616babd1746 to your computer and use it in GitHub Desktop.
An alist function that works with '...' objects.
#' Create an \code{alist}.
#'
#' An alternative to \code{base::alist} that works with \code{...} objects
#' inside a function.
#'
#' An \code{alist} is a list containing possibly unevaluated arguments. The
#' standard implementation of \code{alist} does not work with \code{...} objects
#' inside a function, but this one does. Uses of this function includes partial
#' function application and easier handling of generics that make use of
#' \code{...}, for instance \code{plot}.
#'
#' @param ... objects, possibly named. Can be passed from the calling function.
#' @return A \code{list} with potentially unevaluated arguments.
#' @examples
#' # Make a wrapper around stats::glm that always calls gamma regression.
#'
#' gr = function(...) {
#' dots = alist2(...)
#' dots$family = quote(Gamma)
#' do.call("glm", dots)
#' }
#'
#' gr_list = function(...) {
#' dots = list(...)
#' dots$family = quote(Gamma)
#' do.call("glm", dots)
#' }
#'
#' gr_alist = function(...) {
#' dots = alist(...)
#' dots$family = quote(Gamma)
#' do.call("glm", dots)
#' }
#'
#' # Only 'gr' returns the intended output.
#' gr(formula = disp ~ cyl + mpg, data = mtcars)
#' gr_list(formula = disp ~ cyl + mpg, data = mtcars)
#' gr_alist(formula = disp ~ cyl + mpg, data = mtcars)
#'
#'
#' # Make a thin wrapper over plot that always plots lines instead of points
#' # as the default option.
#'
#' lplot = function(...) {
#' dots = alist2(...)
#' if(is.null(dots$type)) dots$type = "l"
#' do.call("plot", dots)
#' }
#'
#' lplot_list = function(...) {
#' dots = list(...)
#' if(is.null(dots$type)) dots$type = "l"
#' do.call("plot", dots)
#' }
#'
#' lplot_alist = function(...) {
#' dots = alist(...)
#' if(is.null(dots$type)) dots$type = "l"
#' do.call("plot", dots)
#' }
#'
#' z = sort(rnorm(10))
#' w = sort(rnorm(10))
#'
#' # Only lplot yields the intended plot.
#' lplot(z, w, type = "b")
#' lplot_list(z, w, type = "b")
#' lplot_alist(z, w, type = "b")
alist2 = function(...) as.list(substitute(tmp(...)))[-1]
## Testing the alist2 function.
identical(alist2(a = , b = , x = 1, 2, 3, 4),
alist(a = , b = , x = 1, 2, 3, 4))
identical(alist2(1, a = 1:10, b = , 1, 2),
alist(1, a = 1:10, b = , 1, 2))
identical(alist2(1, 2),
alist(1, 2))
identical(alist2(1, 2, a = ),
alist(1, 2, a = ))
identical(alist2(a = , b = ),
alist(a = , b = ))
identical(alist2(a = 1:10, b = 1:10),
alist(a = 1:10, b = 1:10))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment