R拆分分层列表

时间:2016-08-25 21:18:40

标签: r list

我有一份清单清单。我想将此列表拆分为两个列表。 最好在示例中解释一下。所以这是一个例子。

列表包含3个列表。 每个列表元素都是2个data.frames的列表。 (人,车)

df1 = data.frame(id = 1, name = "John")
df2 = data.frame(id = 1, car = "Opel")

list1 = list(person = df1, car = df2)
list2 = list(person = df1, car = df2)
list3 = list(person = df1, car = df2)

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

我想将此列表拆分为两个列表。 第一个应该是personList,第二个是carList。像这样。

> 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

怎么做? 提前谢谢。

2 个答案:

答案 0 :(得分:3)

您可以使用lapply遍历listMain中的每个元素并提取第一个(第二个)元素。我认为这里的关键点是使用[[,就像任何&#34;传统&#34; lapply中的函数。

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

正如@Frank在评论中建议的那样,您也可以按名称进行分组。关键点仍然是你可以像常规函数一样使用[[

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

要阅读此功能的文档,请键入?`[[`

答案 1 :(得分:0)

您可以使用purrr::transpose将列表从3个包含2个元素的元素翻转到2个包含3个元素的元素:

library(purrr)

tListMain <- transpose(listMain)

str(tListMain)

## List of 2
##  $ person: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
##  $ car   :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

...或将每个数据组合成一个带有map的数据框架,版本为lapplydplyr::bind_rows,类似于do.call(rbind, ...)

listMain %>% transpose() %>% map(dplyr::bind_rows)   # purrr pipes well

## $person
##   id name
## 1  1 John
## 2  1 John
## 3  1 John
## 
## $car
##   id  car
## 1  1 Opel
## 2  1 Opel
## 3  1 Opel

如果您真的想要两个单独的列表,purrr::map会自动分组,如果您传递一个字符串或数字:

map(listMain, 'person')

## [[1]]
##   id name
## 1  1 John
## 
## [[2]]
##   id name
## 1  1 John
## 
## [[3]]
##   id name
## 1  1 John

...或使用带有*_df后缀的版本在子集化后简化为data.frame:

map_df(listMain, 'person')

##   id name
## 1  1 John
## 2  1 John
## 3  1 John