Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R - How to extract values for the same named elements across multiple objects of the same type?

Tags:

r

I have a series of objects storing the results of some statistical models in my workspace. Call them "model1", "model2", etc. Each of these models has the same set of named elements attached, $coef, for example. I would like to extract into a list or vector the values stored in a particular element from all objects containing the string "model".

The following code entered at the command line does what I want:

unlist(lapply(parse(text = paste0(ls()[grep("model", ls() )], "$", "coef")), eval))

From this, I've created the following generic function:

get.elements <- function(object, element) {
    unlist(lapply(parse(text = paste0(ls()[grep(object, ls() )], "$", element)), eval))
}

However, when I run this function I get the following error:

Error in parse(text = paste0(ls()[grep(object, ls() )], "$", element)) : 
  <text>:1:1: unexpected '$'
1: $
   ^

Q1. Why does this code work when run from the command line but not as a function, and more importantly, how do I fix it?

Q2. Even better, is there a simpler method that will accomplish the same thing? This seems like such a common task for statisticians and simulation modelers that I would expect some kind of command in the base package, yet I've been unable to find anything. Surely there must be a more elegant way to do this than my cumbersome method.

Thanks for all help.

--Dave

like image 936
David Nolin Avatar asked Sep 25 '12 17:09

David Nolin


2 Answers

You can use map from the purrr package.

l1 <- list(a1 = 3, a2 = 2)
l2 <- list(a1 = 334, a2 = 34)
l3 <- list(a1 = 90, a2 = 112)

l <- list(l1, l2, l3)

purrr::map(l, "a1")

this gives:

### Result
[[1]]
[1] 3

[[2]]
[1] 334

[[3]]
[1] 90
like image 191
slymore Avatar answered Sep 28 '22 12:09

slymore


Q1) The code fails because ls() looks in the environment of the function and since there are no matching objects there,

paste0(ls()[grep(object, ls() )], "$", element)

is equivalent to

paste0("$", element)

To get ls() to look in your workspace, you'd need ls(pos = 1).

Q2) This is a common task, but as far as know there isn't a function to do this because where the models are, what they are called, what objects you want to extract and how you want them returned will depend on your requirements. A slightly neater version of what you propose above would be

nm <- paste0("model", 1:2) # adjust numbers as required
unlist(lapply(nm, function(x) get(nm)$coef))

Alternatively you could put your models in a list and use

modList <- list(model1, model2)
unlist(lapply(modList, "[[", "coefficients"))
like image 26
Heather Turner Avatar answered Sep 28 '22 11:09

Heather Turner