6

Take this object as an example:

expr <- substitute(mean(exp(sqrt(.)), .))

It is a nested list. I want to find every element that matches quote(.).

For example, magrittr's solution matches only the first level of the call:

dots <- c(FALSE, vapply(expr[-1], identical, quote(.), 
                        FUN.VALUE = logical(1)))
dots
[1] FALSE FALSE  TRUE

But I wanted to find every "." in an arbitrary nested list. In this particular case this would be these two dots:

expr[[3]]
expr[[2]][[2]][[2]]

And then these dots should be replaced:

expr[[3]] <- as.name("replacement")
expr[[2]][[2]][[2]] <- as.name("replacement")
expr
# mean(exp(sqrt(replacement)), replacement)

How would you do this?

Carlos Cinelli
  • 10,897
  • 9
  • 42
  • 64

1 Answers1

7

Using a recursive function:

convert.call <- function(x, replacement) {
  if (is.call(x)) as.call(lapply(x, convert.call, replacement=replacement)) else
    if (identical(x, quote(.))) as.name(replacement) else
      x
}

convert.call(expr, "x")
# mean(exp(sqrt(x)), x)
Carlos Cinelli
  • 10,897
  • 9
  • 42
  • 64
flodel
  • 85,263
  • 19
  • 176
  • 215