14
require('fortunes')
fortune('106')
Personally I have never regretted trying not to underestimate my own future stupidity.
   -- Greg Snow (explaining why eval(parse(...)) is often suboptimal, answering a question triggered
      by the infamous fortune(106))
      R-help (January 2007)

So if eval(parse(...)) is suboptimal what is another way to do accomplish this?

I am calling some data from a website using RCurl, what i get after using fromJSON() in the rjson package is a list within a list. Part of the list has the name of an order number that will change depending on the order. The list looks something like:

$orders
$orders$'5810584'
$orders$'5810584'$quantity
[1] 10

$orders$'5810584'$price
[1] 15848

I want to extract the value in $orders$'5810584'$price

Say the list is in the object dat. What I did to extract this using eval(parse(...)) was:

or_ID <- names(dat$orders) # get the order ID number
or_ID
"5810584"
sell_price <- eval(parse(text=paste('dat$',"orders$","'", or_ID, "'", "$price", sep="")))
sell_price
15848

What would be a more optimal way of doing this?

Kevin
  • 1,112
  • 2
  • 15
  • 29
  • doesn't work because or_ID is a character and not numerical. Using, dat$orders[[1]]$price would work – Kevin Jun 14 '12 at 00:28
  • Use `match` to get the position of the name in `names(dat$orders)`. – joran Jun 14 '12 at 00:49
  • 1
    @Kev You can index a list using a character argument. I just recreated your list and tried my suggestion and it worked. If it doesn't work for you then could you paste a reproducible example in so we can actually work with some of the data you have? – Dason Jun 14 '12 at 01:02

1 Answers1

20

Actually the list probably looks a bit different. The '$' convention is somewhat misleading. Try this:

dat[["orders"]][[ or_ID ]][["price"]]

The '$' does not evaluate its arguments, but "[[" does, so or_ID will get turned into "5810584".

IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • Isn't this functionally identical to @Dason 's comment? Tho' I understand your point: the `[[` allows you to generalize to `dat[[foo_ID]][[or_ID]][[bar_ID]]` – Carl Witthoft Jun 14 '12 at 12:06
  • 1
    True. `x[["a"]]` is `x$a`. I was trying to emphasize that point that "[[" allows you to mix levels of evaluation: use either quoted values or symbols that will get evaluated. The x$a formalism is misleading in that it leads the new user to think there might be evaluation of the `a`, when the opposite is the case. – IRTFM Jun 14 '12 at 12:47
  • 4
    Or `dat[[c("orders", or_ID, "price")]]` – hadley Dec 01 '12 at 00:42
  • 1
    Thanks, @hadley. I sometimes get confused about what "[[" can really do. For some reason I rarely succeed with that multiple arguments to "[[" formalism. So apparently I have been applying it to the wrong problems. – IRTFM Dec 01 '12 at 00:49