R语言 如何轻松绑定不同深度的嵌套列表?

jdg4fx2g  于 2022-12-15  发布在  其他
关注(0)|答案(5)|浏览(160)

我有一个数据集,其中一些数据在嵌套列表中。问题是列表的深度各不相同,而且不可能提前知道深度。
下面是一个示例(注:在原始数据集中,列表中没有一个被命名):
'

list1 <- list(
  list("data1"), 
  list(
    list("data2")
  ), 
  list(c("data3", "data4", "data5")),
  list(
    list(
      "data6"
    )
  ), 
  list(c("data7", "data8")), 
  list(
    list(
      list(c("data9", "data10", "data11", "data12"))
    )
  ),
  list("data13")
)

'
我的目标是从这个列表中提取所有的“数据......”到一个新的 Dataframe 中(从某种意义上说,我想把它们绑定起来):
| 诺斯|资料|
| - ------|- ------|
| 1个|数据1|
| 第二章|数据2|
| 三个|数据3、数据4、数据5|
| 四个|数据6|
| 五个|数据7、数据8|
| 六个|数据9、数据10、数据11、数据12|
| 七|数据13|
我尝试了很多选项(重复unlist/map/lapply(list 1,function(l)l1)然后bind_rows或do.call(rbind,...)等),但没有一个有效。最让我困扰的是,我不知道为什么我解不出来。
因此,我的问题是:什么是最简单的方法来绑定不同深度的嵌套列表?

xcitsw88

xcitsw881#

lapply()递归unlist,然后将结果列表传递给tibble(),作为将其放入 Dataframe (tibble是 Dataframe 的一种类型)的方便方式。

list1 <- list(
  list("data1"), 
  list(
    list("data2")
  ), 
  list(c("data3", "data4", "data5")),
  list(
    list(
      "data6"
    )
  ), 
  list(c("data7", "data8")), 
  list(
    list(
      list(c("data9", "data10", "data11", "data12"))
    )
  ),
  list("data13")
)

## consider piping to as.data.frame if you specifically 
## want that format
new_list <- lapply(list1, unlist, recursive = TRUE)

dplyr::tibble(data = new_list)
#> # A tibble: 7 × 1
#>   data     
#>   <list>   
#> 1 <chr [1]>
#> 2 <chr [1]>
#> 3 <chr [3]>
#> 4 <chr [1]>
#> 5 <chr [2]>
#> 6 <chr [4]>
#> 7 <chr [1]>

创建于2022年12月14日,使用reprex v2.0.2

yi0zb3m4

yi0zb3m42#

unlist()每个子列表和其余的将很容易。要获得字符 * 向量 * 形式的数据,您可以应用toString()

data.frame(
  nr = seq_along(list1),
  data = sapply(list1, \(x) toString(unlist(x)))
)

#   nr                          data
# 1  1                         data1
# 2  2                         data2
# 3  3           data3, data4, data5
# 4  4                         data6
# 5  5                  data7, data8
# 6  6 data9, data10, data11, data12
# 7  7                        data13
lrpiutwd

lrpiutwd3#

**1)**假设您需要一个元素为字符向量的列,请尝试以下操作:

DF <- data.frame(nrows = seq_along(list1))
DF$data <- lapply(list1, unlist)

str(DF)
## 'data.frame':   7 obs. of  2 variables:
##  $ nrows: int  1 2 3 4 5 6 7
##  $ data :List of 7
##   ..$ : chr "data1"
##   ..$ : chr "data2"
##   ..$ : chr  "data3" "data4" "data5"
##   ..$ : chr "data6"
##   ..$ : chr  "data7" "data8"
##   ..$ : chr  "data9" "data10" "data11" "data12"
##   ..$ : chr "data13"

**1a)**这个变体也有效。使用I(,,,)在这里很关键,因为没有它代码会发出错误。

DF <- data.frame(nrows = seq_along(list1), data = I(lapply(list1, unlist)))
str(DF)
## 'data.frame':   7 obs. of  2 variables:
##  $ nrows: int  1 2 3 4 5 6 7
##  $ data :List of 7
##   ..$ : chr "data1"
##   ..$ : chr "data2"
##   ..$ : chr  "data3" "data4" "data5"
##   ..$ : chr "data6"
##   ..$ : chr  "data7" "data8"
##   ..$ : chr  "data9" "data10" "data11" "data12"
##   ..$ : chr "data13"
##   ..- attr(*, "class")= chr "AsIs"

**2)**相反,如果您想要一个字符列,其中data列的每个元素都是一个逗号空格分隔的字符串或逗号分隔的字符串,则在运行上面的(1)之后,运行以下命令之一:

DF$data <- sapply(DF$data, toString)
str(DF)
## 'data.frame':   7 obs. of  2 variables:
##  $ nrows: int  1 2 3 4 5 6 7
##  $ data : chr  "data1" "data2" "data3, data4, data5" "data6" ...

DF$data <- sapply(DF$data, paste, collapse = ",")
str(DF)
## 'data.frame':   7 obs. of  2 variables:
##  $ nrows: int  1 2 3 4 5 6 7
##  $ data : chr  "data1" "data2" "data3,data4,data5" "data6" ...
ql3eal8s

ql3eal8s4#

collapse包中有一个非常好的函数unlist2d
unlist2d(list1)的输出为

.id.1 .id.2 .id.3 .id.4   V1     V2     V3     V4
    1     1     1    NA    NA  data1   <NA>   <NA>   <NA>
    2     2     1     1    NA  data2   <NA>   <NA>   <NA>
    3     3     1    NA    NA  data3  data4  data5   <NA>
    4     4     1     1    NA  data6   <NA>   <NA>   <NA>
    5     5     1    NA    NA  data7  data8   <NA>   <NA>
    6     6     1     1     1  data9 data10 data11 data12
    7     7     1    NA    NA data13   <NA>   <NA>   <NA>

有一些选项可用于处理列名和行名称

s3fp2yjn

s3fp2yjn5#

rrapply包中使用rrapply()的另一个选项:

rrapply::rrapply(list1, how = "melt")

#>   L1 L2   L3   L4                         value
#> 1  1  1 <NA> <NA>                         data1
#> 2  2  1    1 <NA>                         data2
#> 3  3  1 <NA> <NA>           data3, data4, data5
#> 4  4  1    1 <NA>                         data6
#> 5  5  1 <NA> <NA>                  data7, data8
#> 6  6  1    1    1 data9, data10, data11, data12
#> 7  7  1 <NA> <NA>                        data13

相关问题