R - 如何使用 list.files 获取多级列表

问题描述 投票:0回答:1

我有这样的文件夹结构:

- ConditionA
     - Subcondition1
          - data1.Rds
          - data2.Rds
     - Subcondition2
          - data1.Rds
          - data2.Rds
- ConditionB
     - Subcondition1
          - data1.Rds
          - data2.Rds
     - Subcondition2
          - data1.Rds
          - data2.Rds

使用

list.files(recursive = T, full.names = T)
给出以下内容:

"./ConditionA/Subcondition1/data1.Rds"
"./ConditionA/Subcondition1/data2.Rds"
"./ConditionA/Subcondition2/data1.Rds"
"./ConditionA/Subcondition2/data2.Rds"
"./ConditionB/Subcondition1/data1.Rds"
"./ConditionB/Subcondition1/data2.Rds"
"./ConditionB/Subcondition2/data1.Rds"
"./ConditionB/Subcondition2/data2.Rds"

但是,我想要的是代表嵌套文件夹结构的列表列表。该列表应该与我将在这里手动构建的列表相同:

sublist1 <- list("data1.Rds", "data2.Rds")
sublist2 <- list("data1.Rds", "data2.Rds")
sublist3 <- list("data1.Rds", "data2.Rds")
sublist4 <- list("data1.Rds", "data2.Rds")

sublist5 <- list(sublist1, sublist2)
names(sublist5) <- c("Condition1", "Condition2")

sublist6 <- list(sublist3, sublist4)
names(sublist6) <- c("Condition1", "Condition2")

final_list <- list(sublist5, sublist6)
names(final_list) <- c("ConditionA", "ConditionB")

让我们看看:

final_list

给出输出:

$ConditionA
$ConditionA$Condition1
$ConditionA$Condition1[[1]]
[1] "data1.Rds"

$ConditionA$Condition1[[2]]
[1] "data2.Rds"


$ConditionA$Condition2
$ConditionA$Condition2[[1]]
[1] "data1.Rds"

$ConditionA$Condition2[[2]]
[1] "data2.Rds"



$ConditionB
$ConditionB$Condition1
$ConditionB$Condition1[[1]]
[1] "data1.Rds"

$ConditionB$Condition1[[2]]
[1] "data2.Rds"


$ConditionB$Condition2
$ConditionB$Condition2[[1]]
[1] "data1.Rds"

$ConditionB$Condition2[[2]]
[1] "data2.Rds"

如何实现自动化而不是手动构建列表?

r list directory-structure
1个回答
0
投票

一个有趣的练习是使用递归函数来完成此操作。

fun <- function(L) {
  len1 <- lengths(L) == 1
  c(
    L[len1],
    if (any(!len1)) lapply(
      split(lapply(L[!len1], `[`, -1), sapply(L[!len1], `[[`, 1)),
      fun)
  )
}

使用类似的树层次结构:

list.files(recursive = TRUE, full.names = TRUE)
# [1] "./ConditionA/Subcondition1/data1.Rds" "./ConditionA/Subcondition1/data2.Rds" "./ConditionA/Subcondition2/data1.Rds"
# [4] "./ConditionA/Subcondition2/data2.Rds" "./ConditionB/Subcondition1/data1.Rds" "./ConditionB/Subcondition1/data2.Rds"
# [7] "./ConditionB/Subcondition2/data1.Rds" "./ConditionB/Subcondition2/data2.Rds"

我们可以这样做:

list.files(recursive = TRUE, full.names = TRUE) |>
  sub("^\\./", "", x = _) |>
  # optional? just stripping the leading "./"
  strsplit("/") |>
  fun() |>
  str()
# List of 2
#  $ ConditionA:List of 2
#   ..$ Subcondition1:List of 2
#   .. ..$ : chr "data1.Rds"
#   .. ..$ : chr "data2.Rds"
#   ..$ Subcondition2:List of 2
#   .. ..$ : chr "data1.Rds"
#   .. ..$ : chr "data2.Rds"
#  $ ConditionB:List of 2
#   ..$ Subcondition1:List of 2
#   .. ..$ : chr "data1.Rds"
#   .. ..$ : chr "data2.Rds"
#   ..$ Subcondition2:List of 2
#   .. ..$ : chr "data1.Rds"
#   .. ..$ : chr "data2.Rds"

(相同的输出,但用

str()
进行了压缩,以便在此处演示。)

© www.soinside.com 2019 - 2024. All rights reserved.