Search code examples
rrecursionformula

replacing a symbol in a formula/expression


Suppose I have a formula or other expression-like object

ee <- a ~ b + c

and want to replace all instances of (for example) symbol b with B. The hacky way to do this is with string substitution:

(ee 
   |> deparse() 
   |> gsub(pattern = "\\<b\\>", replacement = "B") 
   |> as.formula()
)

This works (the result is ee <- a ~ B + c, as desired)

Arguably the better way to do this is to write a recursive function that checks whether a particular element is identical to the target and replaces it with the replacement if so, otherwise calls itself on the elements ... this is a huge pain. Can someone suggest the least painful way to implement this (e.g. an incantation involving rapply()) ... ?

(Related to this question about removing terms from a formula ...)


Solution

  • The recursive function exists already: substitute.

    > do.call(substitute, list(ee, list(b = quote(B))))
    a ~ B + c
    

    Note that

    > substitute(ee, list(b = quote(B)))
    ee
    

    does not work because substitute is a special and does not evaluate its first argument:

    > typeof(substitute)
    [1] "special"