Dan
Dan

Reputation: 31

Can't get rid of extraneous () from expression

I am trying to create a varying label to appear in multiple graphs, using

labl<-substitute(expression(tau[CODE]),list(CODE=i))[2]

where i is the index in the loop.

I get the following:

which is fine except for the "()", that seem to come from the list function. I can't figure out how to get rid of it. I am using the exact same code used in countless other examples and can't find anyone having the same problem.

Thanks for any tips!

Upvotes: 3

Views: 54

Answers (3)

Konrad Rudolph
Konrad Rudolph

Reputation: 545923

Mike’s solution is the right one. But since working with expressions in R is quite unintuitive, here’s a brief explanation why you’re getting the extraneous () when subsetting:

When subsetting an unevaluated expression, R essentially treats the expression as a list. Your original expression looks as follows:

〉 (expr = substitute(expression(tau[CODE]), list(CODE = 1)))
expression(tau[1])
〉 as.list(expr)
[[1]]
expression

[[2]]
tau[1]

Now, when calculating expr[2], you’re slicing that list, but your return value is still a list:

〉 as.list(expr)[2]
[[1]]
tau[1]

And if you treat a list as an unevaluated expression, R always converts it into a function call; in fact, as.call is exactly the opposite of as.list in this context:

〉 as.call(list(1, 2, 3))
1(2, 3)
# same as just `expr`:
〉 as.call(as.list(expr))
expression(tau[1])

And hence:

〉 as.call(as.list(expr)[2])
tau[1]()
# same as:
〉 expr[2]
tau[1]()

So how to prevent this? — By using list subsetting, instead of list slicing:

〉 expr[[2]]
tau[1]

So using [[2]] instead of [2] in your code would work. But the real solution, as shown by Mike, is not to wrap your expression into expression in the first place.

Upvotes: 2

Mike H.
Mike H.

Reputation: 14370

substitute already takes an expression, so no need to wrap your code in expression. You can simply do:

i = 1
substitute(tau[CODE],list(CODE=i))
#tau[1]

Upvotes: 3

93i7hdjb
93i7hdjb

Reputation: 1196

I believe all you need to do is wrap your expression in the as.character() function like so:

> as.character(substitute(expression(tau[CODE]),list(CODE=i))[2])
[1] "tau[1]"

Upvotes: -1

Related Questions