How to efficiently manipulate the contents of nested lists in R

77 Views Asked by At

I am currently working with nested lists containing data on auto parts, here's an example of what that looks like:

Partslist                   <- setNames(list(setNames(vector(mode="list", 5),  paste("L", 3, "_",c("type", "year", "parts available", "last update", "make"), sep=""))), "Partslist")
Partslist$Partslist$L3_make <- setNames(vector(mode="list", 2),  c("BMW", "Toyota"))

Partslist$Partslist$L3_make$BMW$Engine    <-setNames(vector(mode="list", 6),  c("L1_type", "L1_year", "L1_parts available", "L1_last update", "L1_components", "L1_status"))
Partslist$Partslist$L3_make$BMW$Powertrain<-setNames(vector(mode="list", 6),  c("L1_type", "L1_year", "L1_parts available", "L1_last update", "L1_components", "L1_status"))
Partslist$Partslist$L3_make$Toyota$Engine <-setNames(vector(mode="list", 6),  c("L1_type", "L1_year", "L1_parts available", "L1_last update", "L1_components", "L1_status"))
Partslist$Partslist$L3_make$Toyota$other  <-setNames(vector(mode="list", 6),  c("L1_type", "L1_year", "L1_parts available", "L1_last update", "L1_components", "L1_status"))

The main challenge is that these lists are irregular, meaning I do not know a priori how deep the nesting is going to be on individual branches.

What I need is a scalable approach to select and manipulate the data on every level of the nested list, i.e. update prices, quantities, etc.

In short, I find myself unable to come up with an approach that's able to deal with the constantly changing depth of the list.

One possible and easy to implement - yet ugly - way around this, was to form string-expressions of the required manipulations and then use eval(parse(text="")).

That would look something like this:

target.string <- "Autoparts$L3_make$BMW$L2_components$Engine§L1_type" 
parts.data<-"hybrid 3i"

eval(parse(text=paste("target.string", "<-", parts.data, sep="")))

However, I don't want to resort to that, there must be a better way... I am grateful for any suggestion.

1

There are 1 best solutions below

4
On

I don't know all the kinds of things you want to do, but an efficient way to work with deeply nested lists is to use vectors as indices into the top level.

# Your desired index into autoparts was
# autoparts$L3_make$BMW$L2_components$Engine§L1_type

index <- c("L3_make", "BMW", "L2_components", "Engine", "L1_type")

Autoparts[[index]] <- parts.data

An earlier version of this answer said that indexing by name wasn't allowed. That was wrong. What's not allowed is mixing indexing by name with indexing by number. The numbers will get converted to character and be interpreted as names.