mike
mike

Reputation: 23821

Access list element using get()

I'm trying to use get() to access a list element in R, but am getting an error.

example.list <- list()
example.list$attribute <- c("test")
get("example.list") # Works just fine
get("example.list$attribute") # breaks

## Error in get("example.list$attribute") : 
##  object 'example.list$attribute' not found

Any tips? I am looping over a vector of strings which identify the list names, and this would be really useful.

Upvotes: 16

Views: 24359

Answers (4)

Nick Stauner
Nick Stauner

Reputation: 393

flodel's answer worked for my application, so I'm gonna post what I built on it, even though this is pretty uninspired. You can access each list element with a for loop, like so:

#==============  List with five elements of non-uniform length  ================#
example.list=
list(letters[1:5], letters[6:10], letters[11:15], letters[16:20], letters[21:26])
#===============================================================================#
#======  for loop that names and concatenates each consecutive element  ========#
derp=c();            for(i in 1:length(example.list))
{derp=append(derp,eval(parse(text=example.list[i])))}
derp #Not a particularly useful application here, but it proves the point.

I'm using code like this for a function that calls certain sets of columns from a data frame by the column names. The user enters a list with elements that each represent different sets of column names (each set is a group of items belonging to one measure), and the big data frame containing all those columns. The for loop applies each consecutive list element as the set of column names for an internal function* applied only to the currently named set of columns of the big data frame. It then populates one column per loop of a matrix with the output for the subset of the big data frame that corresponds to the names in the element of the list corresponding to that loop's number. After the for loop, the function ends by outputting that matrix it produced.

Not sure if you're looking to do something similar with your list elements, but I'm happy I picked up this trick. Thanks to everyone for the ideas!

"Second example" / tangential info regarding application in graded response model factor scoring:

Here's the function I described above, just in case anyone wants to calculate graded response model factor scores* in large batches...Each column of the output matrix corresponds to an element of the list (i.e., a latent trait with ordinal indicator items specified by column name in the list element), and the rows correspond to the rows of the data frame used as input. Each row should presumably contain mutually dependent observations, as from a given individual, to whom the factor scores in the same row of the ouput matrix belong. Also, I feel I should add that if all the items in a given list element use the exact same Likert scale rating options, the graded response model may be less appropriate for factor scoring than a rating scale model (cf. http://www.rasch.org/rmt/rmt143k.htm).

'grmscores'=function(ColumnNameList,DataFrame)   {require(ltm) #(Rizopoulos,2006)
x = matrix ( NA , nrow = nrow ( DataFrame ), ncol = length ( ColumnNameList ))
for(i in 1:length(ColumnNameList)) #flodel's magic featured below!#
{x[,i]=factor.scores(grm(DataFrame[,    eval(parse(text=   ColumnNameList[i]))]),
resp.patterns=DataFrame[,eval(parse(text= ColumnNameList[i]))])$score.dat$z1}; x}

Reference

*Rizopoulos, D. (2006). ltm: An R package for latent variable modelling and item response theory analyses, Journal of Statistical Software, 17(5), 1-25. URL: http://www.jstatsoft.org/v17/i05/

Upvotes: -2

flodel
flodel

Reputation: 89097

If your strings contain more than just object names, e.g. operators like here, you can evaluate them as expressions as follows:

> string <- "example.list$attribute"
> eval(parse(text = string))
[1] "test"

If your strings are all of the type "object$attribute", you could also parse them into object/attribute, so you can still get the object, then extract the attribute with [[:

> parsed <- unlist(strsplit(string, "\\$"))
> get(parsed[1])[[parsed[2]]]
[1] "test"

Upvotes: 2

Tommy
Tommy

Reputation: 40871

Why not simply:

example.list <- list(attribute="test")
listName <- "example.list"
get(listName)$attribute

# or, if both the list name and the element name are given as arguments:
elementName <- "attribute"
get(listName)[[elementName]]

Upvotes: 6

Josh O&#39;Brien
Josh O&#39;Brien

Reputation: 162451

Here's the incantation that you are probably looking for:

get("attribute", example.list)
# [1] "test"

Or perhaps, for your situation, this:

get("attribute", eval(as.symbol("example.list")))
# [1] "test"

# Applied to your situation, as I understand it...

example.list2 <- example.list 
listNames <- c("example.list", "example.list2")
sapply(listNames, function(X) get("attribute", eval(as.symbol(X))))
# example.list example.list2 
#       "test"        "test" 

Upvotes: 26

Related Questions