# [R] Replacement in an expression - can't use parse()

Peter Dalgaard P.Dalgaard at biostat.ku.dk
Tue Mar 27 16:30:11 CEST 2007

```Daniel Berg wrote:
> Dear all,
>
> Suppose I have a very long expression e. Lets assume, for simplicity, that it is
>
> e = expression(u1+u2+u3)
>
> Now I wish to replace u2 with x and u3 with 1. I.e. the 'new'
> expression, after replacement, should be:
>
>
>> e
>>
> expression(u1+x+1)
>
> My question is how to do the replacement?
>
> I have tried using:
>
>
>> e = parse(text=gsub("u2","x",e))
>> e = parse(text=gsub("u3",1,e))
>>
>
> Even though this works fine in this simple example, the use of parse
> when e is very long will fail since parse has a maximum line length
> and will cut my expressions. I need to keep mode(e)=expression since I
> will use e further in symbolic derivation and division.
>
> Any suggestions are most welcome.
>

However, this is not entirely trivial to apply if you have your
expression already inside an expression() object.

The easy thing to do is

> substitute(u1+u2+u3, list(u2=quote(x),u3=1))
u1 + x + 1

but notice that this "autoquotes" the first argument, so

> substitute(e, list(u2=quote(x),u3=1))
e

which is pretty much useless.

(Arguably it would have been a better design to avoid this feature and
require substitute(quote(.....)....) for the former case.)

The way around this is to add a further layer of substitute() to insert
the value of e:

>
eval(substitute(substitute(call,list(u2=quote(x),u3=1)),list(call=e[[1]])))
u1 + x + 1

Notice that substitute will not go inside expression objects, so we need
to extract the mode "call" object using e[[1]]. Also, the result is
"call" not "expression". You may need an as.expression construct around
the result to get exactly what you asked.

--
O__  ---- Peter Dalgaard             Øster Farimagsgade 5, Entr.B
c/ /'_ --- Dept. of Biostatistics     PO Box 2099, 1014 Cph. K
(*) \(*) -- University of Copenhagen   Denmark          Ph:  (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk)                  FAX: (+45) 35327907

```