我有一个输入数据 struct ,它的叶子 node 是空列表,而父列表只包含子列表.相关信息最终出现在列表属性中,我必须将其提取出来.为此,我需要获得all个列表元素的索引位置,并使用这些坐标遍历列表.{rrapply}一直在为有元素的列表工作,但我想不出如何获得没有非列表子元素的列表的位置.

下面是一个Reprex,显示了我得到{rrapply}的部分,以及它遗漏的部分,以及最后我编写的一个非常老式的解决方案.所以我有一个解决方案,但我想看看我能不能得到{rrapply}来做这件事,并理解为什么我不能让它做我想做的事情.

# stackoverflow_list-element-position-vector.R

library(rrapply)
library(purrr)

# A sample list
lst <-
    list(
        list(),
        list(
            list(),
            list(),
            list()
        ),
        list(a=1:3
             , list()
        )
    )

# Misses all of the empty lists, just the sublist with the name "a":
rrapply(lst,
        f = \(x, .xpos) .xpos,
        how="melt") |>
    pluck("value") |>
    str()
#> List of 1
#>  $ : int [1:2] 3 1

#;; From: https://stackoverflow.com/a/76124073/1022967
#;; Misses the positions of the intermediate nodes, which I need too.
#;; i.e., misses lists at position 2 and 3.
rrapply(lst
        , classes = "list"
        , condition = \(x) length(x) == 0
        , f = \(x) NA
        , how="recurse") |>
    rrapply(f = \(x, .xpos) .xpos
            , how="melt") |>
    pluck("value") |>
    str()
#> List of 6
#>  $ : int 1
#>  $ : int [1:2] 2 1
#>  $ : int [1:2] 2 2
#>  $ : int [1:2] 2 3
#>  $ : int [1:2] 3 1
#>  $ : int [1:2] 3 2

#;; Take a list, return flat list of all of the positions of list
#;; elements.
#;; Real old-school technique...
listEltPos <- function(llst) {
    work_lst <-
        list(list(coord_vec = integer(0), comp = llst))
    output_lst <-
        list()
    
    while (TRUE) {
        if (length(work_lst) == 0) break
        
        # Pop off head of work_lst
        e <-
            pluck(work_lst, 1)
        work_lst <-
            work_lst[-1]
        
        # If element isn't a list, nothing more to process
        if (class(e$comp) != "list") next
        
        # If here, it is a list.  If length is 0, return
        if (length(e$comp) == 0) next
        
        # Otherwise, it has entries.  Find relative coordinate of the entry
        # and add that to the output list and make a list element with that
        # coordinate and the corresponding subelement.
        subElementPositions <-
            seq(length(e$comp))
        
        for (i in subElementPositions) {
            # Append local pos to the overall coordinate vector
            newPosVec <-
                c(e$coord_vec, i)
            sub_e <-
                pluck(e$comp, i)
            
            # Add current new pos to the output queue
            output_lst <-
                append(output_lst, list(newPosVec))
            
            # Append subelements and their updated positions to the work queue
            work_lst <-
                append(work_lst, list(list(coord_vec=newPosVec, comp=sub_e)))
        }
        rm(i)
    }

    output_lst
}

#;; This is what I am hoping for
listEltPos(lst) |>
    str()
#> List of 8
#>  $ : int 1
#>  $ : int 2
#>  $ : int 3
#>  $ : int [1:2] 2 1
#>  $ : int [1:2] 2 2
#>  $ : int [1:2] 2 3
#>  $ : int [1:2] 3 1
#>  $ : int [1:2] 3 2

创建于2023-05-03年第reprex v2.0.2

推荐答案

使用rrapply()的一种可能方法是使用how = "recurse"遍历嵌套列表,并通过将它们赋给全局变量(在函数作用域之外)来跟踪遇到的所有值.xpos:

library(rrapply)

## initialize empty list
allpos <- list()

## walk nested list and append indices to `allpos`
invisible(
  rrapply(
    lst,
    classes = c("list", "integer"),
    how = "recurse",
    f = \(x, .xpos) {
      allpos <<- append(allpos, list(.xpos))
      x
    }
  )
)

str(allpos)
#> List of 8
#>  $ : int 1
#>  $ : int 2
#>  $ : int [1:2] 2 1
#>  $ : int [1:2] 2 2
#>  $ : int [1:2] 2 3
#>  $ : int 3
#>  $ : int [1:2] 3 1
#>  $ : int [1:2] 3 2

注意:对于非常大的列表,这将不是很有效,在这种情况下,提前确定allpos的大小可能更好,而不是迭代地向列表追加新值.

R相关问答推荐

如何使用Cicerone指南了解R Shiny中传单 map 的元素?

有没有方法将paste 0功能与列表结合起来?

在ggplot的注释表格中突出显示最大值

如果行和列名以相同的开头,将矩阵值设置为0

R形式的一维数字线/箱形图样式图表

在值和NA的行顺序中寻找中断模式

获取列中值更改的行号

使用case_match()和char数组重新编码值

如何使下一个按钮只出现在Rshiny 的一段时间后?""

提取具有连续零值的行,如果它们前面有R中的有效值

当我们有多个特殊字符时,使用gsub删除名称和代码'

多个模拟序列间的一种预测回归关系

条形图顶部与其错误条形图不对齐

使用ggplot2中的sec_axis()调整次轴

向R中的数据帧添加一列,该列统计另一列中每个唯一值的二进制观测值的数量

判断函数未加载R中的库

访问数据帧中未定义的列时出现R错误

Ggplot2如何找到存储在对象中的残差和拟合值?

使用&Fill&Quot;在gglot中创建 colored颜色 渐变

R dplyr::带有名称注入(LHS of:=)的函数,稍后在:=的RHS上引用