如何访问不同深度嵌套列表中的第一个对象?

Lul*_*ulY 16 select r list nested-lists

我需要访问 a 的第一个元素list。问题在于列表的嵌套深度不同。这是一个例子:

list1 <- list(ts(1:100),
              list(1:19,
                   factor(letters)))

list2 <- list(list(list(ts(1:100), data.frame(a= rnorm(100))),
                   matrix(rnorm(10))),
              NA)
Run Code Online (Sandbox Code Playgroud)

我的预期输出是获取ts(1:100)两个列表的时间序列,即list1[[1]]list2[[1]][[1]][[1]]。我尝试过不同的东西,其中包括lapply(list2, `[[`, 1),这里不起作用。

hen*_*ryn 14

另一个基本的 R 解决方案 - 您可以使用递归函数来完成此操作:

list1 <- list(ts(1:100),
              list(1:19,
                   factor(letters)))

list2 <- list(list(list(ts(1:100), data.frame(a= rnorm(100))),
                   matrix(rnorm(10))),
              NA)


recursive_fun <- function(my_list) {
  
  if (inherits(my_list, 'list')) {
    Recall(my_list[[1]])
  } else {
    my_list
  }
  
}
Run Code Online (Sandbox Code Playgroud)

输出:

> recursive_fun(list1)
Time Series:
Start = 1 
End = 100 
Frequency = 1 
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30
 [31]  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60
 [61]  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
 [91]  91  92  93  94  95  96  97  98  99 100

> recursive_fun(list2)
Time Series:
Start = 1 
End = 100 
Frequency = 1 
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30
 [31]  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60
 [61]  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
 [91]  91  92  93  94  95  96  97  98  99 100
Run Code Online (Sandbox Code Playgroud)

  • 但“is.list()”也会在“data.frame”上返回“TRUE”。我*认为* `inherits(my_list, 'list')` 更好。 (3认同)
  • @sindri_baldur是的,我同意这一点 - 也许在“if”条件下“length(my_list) &gt; 0”,以防万一有一个空列表,也值得做 (2认同)

Maë*_*aël 10

您可以使用rrapply::rrapply

library(rrapply)
firstList1 <- rrapply(list1, how = "flatten")[[1]]
firstList2 <- rrapply(list2, how = "flatten")[[1]]

all.equal(firstList1, firstList2)
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)

输出

> rrapply(list1, how = "flatten")[[1]]

Time Series:
Start = 1 
End = 100 
Frequency = 1 
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26
 [27]  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52
 [53]  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78
 [79]  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100
Run Code Online (Sandbox Code Playgroud)


Moo*_*per 5

使用while循环:

x <- list1
while (inherits(x <- x[[1]], "list")) {}
x
#> Time Series:
#> Start = 1 
#> End = 100 
#> Frequency = 1 
#>   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18
#>  [19]  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36
#>  [37]  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54
#>  [55]  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72
#>  [73]  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
#>  [91]  91  92  93  94  95  96  97  98  99 100

x <- list2
while (inherits(x <- x[[1]], "list")) {}
x
#> Time Series:
#> Start = 1 
#> End = 100 
#> Frequency = 1 
#>   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18
#>  [19]  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36
#>  [37]  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54
#>  [55]  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72
#>  [73]  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
#>  [91]  91  92  93  94  95  96  97  98  99 100
Run Code Online (Sandbox Code Playgroud)