Reputation: 1595
I am automating the creation of a series of plots each of which is based on a class of chemicals (e.g., metals, PCBs, etc.); for reasons I'll leave out, I am plotting the legend outside of the plot and using negative values for the inset
argument for the legend()
function to do this (e.g., inset = c(-0.2, 0)
). As each of the chemical classes requires different values for the inset
I thought of creating a hash table using the hash
package to store the values needed for each chemical class. However, in order to store these in the hash table I was storing the vector of values as a string (e.g., "c(-0.2, 0)").
My code for the hash table looks like this:
legend.hash <- hash(chem.class, c('c(-0.2, 0)', 'c(-0.2, 0)', 'c(-0.25, -0.4)', 'c(-0.25, -0.3)', 'c(-0.2, 0)', 'c(-0.4, -0.2)', 'c(-0.2, 0)', 'c(-0.2, 0)'))
where chem.class
is a vector of chemical classes.
Retrieving the values from the resulting hash table are obviously as a string "c(-0.2, 0)"
, is there a way of converting this string of text so that R interprets it as a function that could be used like the following: legend(..., inset = legend.hash[[chem.class[i]]])
?
Or is there a better way to implement this using the traditional graphics system?
Upvotes: 3
Views: 349
Reputation: 49680
If you really want to convert a string with 2 number values in it into a vector of numbers then consider using the strapply
function from the gsubfn
package. This way you avoid the parse
function and all the potential headaches that come with it. It may also end up being faster.
If you change the strings to just the numbers and a seperator (without the 'c' and parens) then you could just use as.numeric
on the result of strsplit
which may be even faster.
Upvotes: 1
Reputation: 49680
It may work better to position your legend using the grconvertX
and grconvertY
functions rather than using negative insets.
Upvotes: 1
Reputation: 108633
The classic way of executing a string as if it was a function is by using eval()
and parse()
:
> eval(parse(text="c(-0.2,0)"))
[1] -0.2 0.0
But I really wonder why you insist on using a hash instead of a simple list.
legend.hash <- list(c(-0.2, 0), c(-0.2, 0), c(-0.25, -0.4), c(-0.25, -0.3),
c(-0.2, 0), c(-0.4, -0.2), c(-0.2, 0), c(-0.2, 0))
names(legend.hash) <- chem.class
would allow you to use the exact construct you're using now, without all the tricky bits and pieces of eval()
and parse()
, especially thinking about the infamous fortune(106)
:
> require(fortunes)
> fortune(106)
If the answer is parse() you should usually rethink the question.
-- Thomas Lumley
R-help (February 2005)
Upvotes: 7