aeliv002 - 3 months ago 22
R Question

# R split hierarchical list of lists

I have a list of lists. I want to split this list into two list.
It is better to explain in example. So here is example.

List consist of 3 lists.
Each of the list element is a list of 2 data.frames. (person, car)

``````> df1 = data.frame(id = 1, name = "John")
> df2 = df1
> df3 = df1
> df4 = data.frame(id = 1, car = "Opel")
> df5 = df4
> df6 = df5
> list1 = list(person = df1,car=df4)
> list2 = list(person = df2,car=df5)
> list3 = list(person = df3,car=df6)
> listMain = list(list1,list2,list3)
> str(listMain)
List of 3
\$ :List of 2
..\$ person:'data.frame':  1 obs. of  2 variables:
.. ..\$ id  : num 1
.. ..\$ name: Factor w/ 1 level "John": 1
..\$ car   :'data.frame':  1 obs. of  2 variables:
.. ..\$ id : num 1
.. ..\$ car: Factor w/ 1 level "Opel": 1
\$ :List of 2
..\$ person:'data.frame':  1 obs. of  2 variables:
.. ..\$ id  : num 1
.. ..\$ name: Factor w/ 1 level "John": 1
..\$ car   :'data.frame':  1 obs. of  2 variables:
.. ..\$ id : num 1
.. ..\$ car: Factor w/ 1 level "Opel": 1
\$ :List of 2
..\$ person:'data.frame':  1 obs. of  2 variables:
.. ..\$ id  : num 1
.. ..\$ name: Factor w/ 1 level "John": 1
..\$ car   :'data.frame':  1 obs. of  2 variables:
.. ..\$ id : num 1
.. ..\$ car: Factor w/ 1 level "Opel": 1
``````

I want to split this list into two lists.
First one should be personList, second is carList. Like this.

``````> listPerson <- list(df1,df2,df3)
> str(listPerson)
List of 3
\$ :'data.frame':   1 obs. of  2 variables:
..\$ id  : num 1
..\$ name: Factor w/ 1 level "John": 1
\$ :'data.frame':   1 obs. of  2 variables:
..\$ id  : num 1
..\$ name: Factor w/ 1 level "John": 1
\$ :'data.frame':   1 obs. of  2 variables:
..\$ id  : num 1
..\$ name: Factor w/ 1 level "John": 1
> listCars <- list(df4,df5,df6)
> str(listCars)
List of 3
\$ :'data.frame':   1 obs. of  2 variables:
..\$ id : num 1
..\$ car: Factor w/ 1 level "Opel": 1
\$ :'data.frame':   1 obs. of  2 variables:
..\$ id : num 1
..\$ car: Factor w/ 1 level "Opel": 1
\$ :'data.frame':   1 obs. of  2 variables:
..\$ id : num 1
..\$ car: Factor w/ 1 level "Opel": 1
``````

How to do that?
Thanks in advance.

Answer

You can use `lapply` to go through each element in `listMain` and extract the first (second) element. I think the key point here is the use of `[[` like any "traditional" function in `lapply`.

``````listPerson <- lapply(listMain, `[[`, 1)
listCar <- lapply(listMain, `[[`, 2)
``````

As @Frank suggests in the comment, you can subset by name as well. The key point remains that you can use `[[` like regular function.

``````listPerson <- lapply(listMain, `[[`, "person")
``````

To read the docs for this function, type `?`[[``.

Source (Stackoverflow)
Comments