索引嵌套列表/环境的有效(或最有效)方法是什么?

时间:2011-11-20 22:31:42

标签: list r indexing nested

我喜欢上下文中列表的灵活性,其中正式类的对象太不灵活。基本上,它们可用于映射处理我们在操作系统的标准文件系统中使用的树结构的方式。

然而,为了掌握超过3或4的“嵌套度”,您需要一种计算嵌套列表索引的方法。一旦你有这样的索引,选择一个特定的分支,更新它,在列表中添加新的分支并不是很困难,简而言之:做我们在操作系统文件系统中对文件和文件夹做的所有事情。< / p>

实施例

基本上,str(object)已完成工作,但只输出文本(capture.output(str(object))。我将其转换为数据框架结构

示例列表

setClass("TESTCLASS_X", representation=representation(a="numeric"))
setRefClass("TESTCLASS_Y", fields=list(a="numeric"))

src <- list(
    a=list(
        a.1=list(a.1.1 = 1, a.1.2 = 1:5, a.1.3 = integer(0)),
        a.2=list(a.2.1="a", a.2.2=c("a", "b", "c", "d", "e"), a.2.3=character()),
        a.3=list(a.3.1=1.5, a.3.2=c(1.5, 2.5), a.3.3=numeric()), 
        a.4=list(a.4.1=1+1i, a.4.2=c(0.1+0.3i, 0.2+0.2i, 0.1+0.1i), a.4.3=complex()),  
        a.5=list(a.5.1 = TRUE, a.5.2 = c(TRUE, TRUE, TRUE), a.5.3 = logical())
    ), 
    b=list(
        b.1=list(
            b.1.1=list(b.1.1.1 =matrix(1, ncol=1),
                b.1.1.2=matrix(c(1:4), ncol=2, dimnames=list(NULL, c("a","b"))),
                b.1.1.3=matrix()
            ),
            b.1.2=list(b.1.2.1=data.frame(1), b.1.2.2=data.frame(a=1:3, b=1:3),
                b.1.2.3=data.frame() 
            )
        ),
        b.2=list(
            b.2.1=list(b.2.1.1=list(a=1), b.2.1.2=list(a=1:2, b=letters[1:2]),
                b.2.1.3=list(a=1:2, b="a", c=1:3, d=FALSE, e=1:5), b.2.1.4=list()
            )
        )
    ),
    c=list(
        c.1=list(c.1.1=new.env(), c.1.2=new("TESTCLASS_X", a=1:5), 
            c.1.3=new("TESTCLASS_Y", a=1:5))
    )
)

所需的输出

                    name pos is.top is.bottom       class is.s4  dim
1                      a   1   TRUE     FALSE        list FALSE    5
2                  a/a.1   2  FALSE     FALSE        list FALSE    3
3            a/a.1/a.1.1   3  FALSE      TRUE     numeric FALSE    1
4            a/a.1/a.1.2   3  FALSE      TRUE     integer FALSE    5
5            a/a.1/a.1.3   3  FALSE      TRUE     integer FALSE    0
6                  a/a.2   2  FALSE     FALSE        list FALSE    3
7            a/a.2/a.2.1   3  FALSE      TRUE   character FALSE    1
8            a/a.2/a.2.2   3  FALSE      TRUE   character FALSE    5
9            a/a.2/a.2.3   3  FALSE      TRUE   character FALSE    0
10                 a/a.3   2  FALSE     FALSE        list FALSE    3
11           a/a.3/a.3.1   3  FALSE      TRUE     numeric FALSE    1
12           a/a.3/a.3.2   3  FALSE      TRUE     numeric FALSE    2
13           a/a.3/a.3.3   3  FALSE      TRUE     numeric FALSE    0
14                 a/a.4   2  FALSE     FALSE        list FALSE    3
15           a/a.4/a.4.1   3  FALSE      TRUE     complex FALSE    1
16           a/a.4/a.4.2   3  FALSE      TRUE     complex FALSE    3
17           a/a.4/a.4.3   3  FALSE      TRUE     complex FALSE    0
18                 a/a.5   2  FALSE     FALSE        list FALSE    3
19           a/a.5/a.5.1   3  FALSE      TRUE     logical FALSE    1
20           a/a.5/a.5.2   3  FALSE      TRUE     logical FALSE    3
21           a/a.5/a.5.3   3  FALSE      TRUE     logical FALSE    0
22                     b   1   TRUE     FALSE        list FALSE    2
23                 b/b.1   2  FALSE     FALSE        list FALSE    2
24           b/b.1/b.1.1   3  FALSE     FALSE        list FALSE    3
25   b/b.1/b.1.1/b.1.1.1   4  FALSE      TRUE      matrix FALSE  1-1
26   b/b.1/b.1.1/b.1.1.2   4  FALSE      TRUE      matrix FALSE  2-2
27   b/b.1/b.1.1/b.1.1.3   4  FALSE      TRUE      matrix FALSE  1-1
28           b/b.1/b.1.2   3  FALSE     FALSE        list FALSE    3
29   b/b.1/b.1.2/b.1.2.1   4  FALSE      TRUE  data.frame FALSE  1-1
30   b/b.1/b.1.2/b.1.2.2   4  FALSE      TRUE  data.frame FALSE  3-2
31   b/b.1/b.1.2/b.1.2.3   4  FALSE      TRUE  data.frame FALSE  0-0
32                 b/b.2   2  FALSE     FALSE        list FALSE    1
33           b/b.2/b.2.1   3  FALSE     FALSE        list FALSE    4
34   b/b.2/b.2.1/b.2.1.1   4  FALSE     FALSE        list FALSE    1
35 b/b.2/b.2.1/b.2.1.1/a   5  FALSE      TRUE     numeric FALSE    1
36   b/b.2/b.2.1/b.2.1.2   4  FALSE     FALSE        list FALSE    2
37 b/b.2/b.2.1/b.2.1.2/a   5  FALSE      TRUE     integer FALSE    2
38 b/b.2/b.2.1/b.2.1.2/b   5  FALSE      TRUE   character FALSE    2
39   b/b.2/b.2.1/b.2.1.3   4  FALSE     FALSE        list FALSE    5
40 b/b.2/b.2.1/b.2.1.3/a   5  FALSE      TRUE     integer FALSE    2
41 b/b.2/b.2.1/b.2.1.3/b   5  FALSE      TRUE   character FALSE    1
42 b/b.2/b.2.1/b.2.1.3/c   5  FALSE      TRUE     integer FALSE    3
43 b/b.2/b.2.1/b.2.1.3/d   5  FALSE      TRUE     logical FALSE    1
44 b/b.2/b.2.1/b.2.1.3/e   5  FALSE      TRUE     integer FALSE    5
45   b/b.2/b.2.1/b.2.1.4   4  FALSE     FALSE        list FALSE    0
46                     c   1   TRUE     FALSE        list FALSE    1
47                 c/c.1   2  FALSE     FALSE        list FALSE    3
48           c/c.1/c.1.1   3  FALSE      TRUE environment FALSE <NA>
49           c/c.1/c.1.2   3  FALSE      TRUE TESTCLASS_X  TRUE    1
50           c/c.1/c.1.3   3  FALSE      TRUE TESTCLASS_Y  TRUE    1

编辑2011-11-21

Spacedman问我,这不仅仅是深度优先搜索的结果。嗯,肯定是,但是

  1. 我挣扎着它的递归本质
  2. 我认为“手动”深度优先可能总是比依赖capture.output(str()效率低,因为那是基于C(IIRC)
  3. 这与我的第一个深度优先方法类似:

    src取自上方

    objIndex <- function(src){
        out <- lapply(1:length(src), function(x){
            if(class(src[[x]]) == "list"){
                if(length(src[[x]])){
                    df.1 <- objIndex(src=src[[x]])
                } else {
                    df.1 <- data.frame(
                        path=names(src[x]),
                        pos=NA,
                        is.top=FALSE,
                        is.bottom=TRUE,
                        class=class(src[[x]]),
                        dim=length(src[[x]])
                    )    
                }
            } else {
                df.1 <- data.frame(
                    path=ifelse(is.null(names(src[x])), NA, names(src[x])),
                    pos=NA,
                    is.top=FALSE,
                    is.bottom=TRUE,
                    class=class(src[[x]]),
                    dim=length(src[[x]])
                )    
            }  
            df.1
        })
        return(out)
    }
    > objIndex(src, df=NULL)
    [[1]]
    [[1]][[1]]
    [[1]][[1]][[1]]
       path pos is.top is.bottom   class dim
    1 a.1.1  NA  FALSE      TRUE numeric   1
    
    [[1]][[1]][[2]]
       path pos is.top is.bottom   class dim
    1 a.1.2  NA  FALSE      TRUE integer   5
    
    [[1]][[1]][[3]]
       path pos is.top is.bottom   class dim
    1 a.1.3  NA  FALSE      TRUE integer   0
    
    
    [[1]][[2]]
    [[1]][[2]][[1]]
       path pos is.top is.bottom     class dim
    1 a.2.1  NA  FALSE      TRUE character   1
    
    [[1]][[2]][[2]]
       path pos is.top is.bottom     class dim
    1 a.2.2  NA  FALSE      TRUE character   5
    
    [[1]][[2]][[3]]
       path pos is.top is.bottom     class dim
    1 a.2.3  NA  FALSE      TRUE character   0
    
    
    [[1]][[3]]
    [[1]][[3]][[1]]
       path pos is.top is.bottom   class dim
    1 a.3.1  NA  FALSE      TRUE numeric   1
    
    [[1]][[3]][[2]]
       path pos is.top is.bottom   class dim
    1 a.3.2  NA  FALSE      TRUE numeric   2
    
    [[1]][[3]][[3]]
       path pos is.top is.bottom   class dim
    1 a.3.3  NA  FALSE      TRUE numeric   0
    
    
    [[1]][[4]]
    [[1]][[4]][[1]]
       path pos is.top is.bottom   class dim
    1 a.4.1  NA  FALSE      TRUE complex   1
    
    [[1]][[4]][[2]]
       path pos is.top is.bottom   class dim
    1 a.4.2  NA  FALSE      TRUE complex   3
    
    [[1]][[4]][[3]]
       path pos is.top is.bottom   class dim
    1 a.4.3  NA  FALSE      TRUE complex   0
    
    
    [[1]][[5]]
    [[1]][[5]][[1]]
       path pos is.top is.bottom   class dim
    1 a.5.1  NA  FALSE      TRUE logical   1
    
    [[1]][[5]][[2]]
       path pos is.top is.bottom   class dim
    1 a.5.2  NA  FALSE      TRUE logical   3
    
    [[1]][[5]][[3]]
       path pos is.top is.bottom   class dim
    1 a.5.3  NA  FALSE      TRUE logical   0
    
    
    
    [[2]]
    [[2]][[1]]
    [[2]][[1]][[1]]
    [[2]][[1]][[1]][[1]]
         path pos is.top is.bottom  class dim
    1 b.1.1.1  NA  FALSE      TRUE matrix   1
    
    [[2]][[1]][[1]][[2]]
         path pos is.top is.bottom  class dim
    1 b.1.1.2  NA  FALSE      TRUE matrix   4
    
    [[2]][[1]][[1]][[3]]
         path pos is.top is.bottom  class dim
    1 b.1.1.3  NA  FALSE      TRUE matrix   1
    
    
    [[2]][[1]][[2]]
    [[2]][[1]][[2]][[1]]
         path pos is.top is.bottom      class dim
    1 b.1.2.1  NA  FALSE      TRUE data.frame   1
    
    [[2]][[1]][[2]][[2]]
         path pos is.top is.bottom      class dim
    1 b.1.2.2  NA  FALSE      TRUE data.frame   2
    
    [[2]][[1]][[2]][[3]]
         path pos is.top is.bottom      class dim
    1 b.1.2.3  NA  FALSE      TRUE data.frame   0
    
    
    
    [[2]][[2]]
    [[2]][[2]][[1]]
    [[2]][[2]][[1]][[1]]
    [[2]][[2]][[1]][[1]][[1]]
       path pos is.top is.bottom   class dim
    1 <<1>>  NA  FALSE      TRUE numeric   1
    
    
    [[2]][[2]][[1]][[2]]
    [[2]][[2]][[1]][[2]][[1]]
      path pos is.top is.bottom   class dim
    1    a  NA  FALSE      TRUE integer   2
    
    [[2]][[2]][[1]][[2]][[2]]
      path pos is.top is.bottom     class dim
    1    b  NA  FALSE      TRUE character   2
    
    
    [[2]][[2]][[1]][[3]]
    [[2]][[2]][[1]][[3]][[1]]
       path pos is.top is.bottom   class dim
    1 <<1>>  NA  FALSE      TRUE integer   2
    
    [[2]][[2]][[1]][[3]][[2]]
       path pos is.top is.bottom     class dim
    1 <<2>>  NA  FALSE      TRUE character   1
    
    [[2]][[2]][[1]][[3]][[3]]
       path pos is.top is.bottom   class dim
    1 <<3>>  NA  FALSE      TRUE integer   3
    
    [[2]][[2]][[1]][[3]][[4]]
       path pos is.top is.bottom   class dim
    1 <<4>>  NA  FALSE      TRUE logical   1
    
    [[2]][[2]][[1]][[3]][[5]]
       path pos is.top is.bottom   class dim
    1 <<5>>  NA  FALSE      TRUE integer   5
    
    
    [[2]][[2]][[1]][[4]]
         path pos is.top is.bottom class dim
    1 b.2.1.4  NA  FALSE      TRUE  list   0
    
    
    
    
    [[3]]
    [[3]][[1]]
    [[3]][[1]][[1]]
       path pos is.top is.bottom       class dim
    1 c.1.1  NA  FALSE      TRUE environment   0
    
    [[3]][[1]][[2]]
       path pos is.top is.bottom       class dim
    1 c.1.2  NA  FALSE      TRUE TESTCLASS_X   1
    
    [[3]][[1]][[3]]
       path pos is.top is.bottom       class dim
    1 c.1.3  NA  FALSE      TRUE TESTCLASS_Y   1
    

2 个答案:

答案 0 :(得分:2)

可以使用rapply获得部分解决方案。这仅计算结束节点的值,因此您可以获得数据框中is.bottomTRUE的部分。通过检查名称可以获得表格的其余部分,但我怀疑它很费劲,而且这些节点相当无聊(只有class = "list"is.S4 = FALSE)。

classis.S4列很容易获得。

out_class <- rapply(src, class)    
out_isS4 <- rapply(src, isS4) 

我不太确定您使用dim列做了什么,但类似的调用应该让您开始。

out_dim <- rapply(src, length)

获取你想要的名字,我们使用你想要斜线分隔符的技巧,其中有一个点后跟一个字母。如果您在列表中没有命名元素,这可能会中断,但我没有对其进行测试。

sep <- "/"
out_name <- gsub("\\.(?=[[:alpha:]])", sep, names(out_class), perl = TRUE)

同样,嵌套的深度可以从刚刚添加到名称中的斜杠数中找到。

out_pos <- sapply(strsplit(out_name, sep), length) 

最后,我们将这些组合成一个数据框。

(out <- data.frame(
  name = out_name,
  pos = out_pos,
  class = out_class,
  is.S4 = out_isS4,
  dim = out_dim  
))

答案 1 :(得分:0)

经过两次糟糕的尝试后,我想出了一个发布的here。然而,它仍然感觉这太复杂了,而且可以更容易实现。

对于混乱的格式我很抱歉!我会在几天内将代码移动到Github仓库。

相关问题