Skip to content

Instantly share code, notes, and snippets.

@hadley
Created January 28, 2014 13:34
Show Gist options
  • Save hadley/8667699 to your computer and use it in GitHub Desktop.
Save hadley/8667699 to your computer and use it in GitHub Desktop.

Limitations of lapply()

lapply() is a really useful function but it has some limitations. For example, with lapply() there is no way to:

  • add new elements
  • remove existing elements
  • change the names of list elements

To overcome these problems we could create a variant of lapply() than I'm going to call fapply() (where f is for flexible). Rather than calling the supplied function with with an element of the list extract with [[, it will call it with a sub-list extracted with [.

fapply <- function(x, f, ...) {
  out <- vector("list", length(x))
  for (i in seq_along(x)) {
    res <- f(x[i], ...)
    stopifnot(is.list(x) && is.vector(x))
    out[[i]] <- res
  }

  unlist(out, recursive = FALSE)
}

We can then use fapply() to:

  • Change names:

    x <- list(a = 1, b = 2, c = 3)
    fapply(x, function(x) setNames(x, toupper(names(x))))
    
  • Add new elements to the list:

    x <- list(a = 1, b = 2, c = 3)
    fapply(x, function(x) rep(x, x[[1]]))
    
  • Remove elements from the list:

    x <- list(a = 1, b = 2, c = 3)
    fapply(x, function(x) if (x[[1]] > 2) x)
    

The difference between lapply() and fapply() is a lot like the difference bewteen [[ and [. In lapply(), f takes an element of a list and returns a new element; in fapply(), f takes a sublist and returns a sublist. An important property of fapply() is the type of object that f takes as input and returns as output is the same as the original x, a list.

Monads are a generalisation of this idea. If you have an object, like a list, that provides a function that works like fapply(), then it's a monad. It turns out that you can implement fapply() in terms of some simpler functions, which are what monads are usually defined in terms of.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment