Search code examples
rgetapostrophe

Access data deep in a structure using get()


I have a p structure in R memory and I'm trying to access the Rate column of the matrix.

When I type p$6597858$Sample in the console, I get ...

 p$`6597858`$Sample
        Rate             Available                 X                    Y
[1,]    1.01              1520.93                0.00                  0.0
[2,]    1.02               269.13                0.00                  0.0
[3,]    1.03               153.19                0.00                  0.0
[4,]    1.04               408.80                0.00                  0.0

and so on ...

Within my code when I try to

get("p$`6597858`$Sample[,1]") 

I get this returned ...

object 'p$`6597858`$Sample[ ,1]' not found

Is this an apostrophe problem?


Solution

  • Neither the $ nor the [[ operator work within get() (because p[[1]] is not an R object, it's a component of the object p).

    You could try

    p <- list(`6597858`=list(Sample=data.frame(Rate=1:3,Available=2:4)))
    z <- eval(parse(text="p$`6597858`$Sample[,1]"))
    

    but it's probably a bad idea. Is there a reason that

    z <- p[["6597858"]][["Sample"]][,"Rate"]
    

    doesn't do what you want?

    You can do this dynamically by using character variables to index, still without using get: for example

    needed <- 1234
    x <- p[[as.character(needed)]][["Sample"]][,"Rate"]
    

    (edit: suggested by Hadley Wickham in comments) or

    x <- p[[c(as.character(needed),"Sample","Rate")]]
    

    (if the second-lowest-level element is a data frame or list: if it's a matrix, this alternative won't work, you would need p[[c(as.character(needed),"Sample")]][,"Rate"] instead)

    This is a situation where figuring out the idiom of the language and working with it (rather than struggling against it) will pay off ...

    library(fortunes)
    fortune(106)
    
    If the answer is parse() you should usually rethink the question.
       -- Thomas Lumley
          R-help (February 2005)
    

    In general,

    • extracting elements directly from lists is better (safer, leads to less convoluted code) than using get()
    • using non-standard names for list elements (i.e. those such as pure numbers that need to be protected by backticks) is unwise
    • [[ is more robust than $