测试嵌套列表是否具有相同的结构

时间:2018-11-06 19:42:37

标签: r

说我有一些复杂的嵌套列表:

x <- list(list(a = array(1:24, c(2,3,4)), b = array(1:6, c(3,1,2))), list(c = 'string1'), list(d = c(T, F, F), e = c(F, F, T)))
y <- list(list(a = array(24:1, c(2,3,4)), b = array(2:7, c(3,1,2))), list(c = 'string2'), list(d = c(F, F, F), e = c(T, T, T)))
z <- list(list(a = array(24:1, c(3,2,4)), b = array(2:7, c(3,1,2))), list(c = 'string2'), list(d = c(F, F, F), e = c(T, T, T)))

是否有一种简单的方法来测试其中两个列表的结构是否相同?

我正在寻找一些函数,如果列表具有相同的嵌套,名称,长度和元素类型,这些函数将返回TRUE。例如:

> all.equal.structure(x, y)
[1] TRUE   # Values are different, but that doesn't matter
> all.equal.structure(y, z)
[1] FALSE  # Dimensions of a are different

1 个答案:

答案 0 :(得分:1)

可以str函数进行操作以仅比较结构。默认情况下,它输出到终端并返回NULL,但是我们可以使用capture.output来获得其输出值:

> x.str <- capture.output(str(x))
> y.str <- capture.output(str(y))
> x.str
[1] "List of 3"                                            
[2] " $ :List of 2"                                        
[3] "  ..$ a: int [1:2, 1:3, 1:4] 1 2 3 4 5 6 7 8 9 10 ..."
[4] "  ..$ b: int [1:3, 1, 1:2] 1 2 3 4 5 6"               
[5] " $ :List of 1"                                        
[6] "  ..$ c: chr \"string1\""                             
[7] " $ :List of 2"                                        
[8] "  ..$ d: logi [1:3] TRUE FALSE FALSE"                 
[9] "  ..$ e: logi [1:3] FALSE FALSE TRUE"      
> y.str
[1] "List of 3"                                                     
[2] " $ :List of 2"                                                 
[3] "  ..$ a: int [1:2, 1:3, 1:4] 24 23 22 21 20 19 18 17 16 15 ..."
[4] "  ..$ b: int [1:3, 1, 1:2] 2 3 4 5 6 7"                        
[5] " $ :List of 1"                                                 
[6] "  ..$ c: chr \"string2\""                                      
[7] " $ :List of 2"                                                 
[8] "  ..$ d: logi [1:3] FALSE FALSE FALSE"                         
[9] "  ..$ e: logi [1:3] TRUE TRUE TRUE"    

str还有一个参数vec.len,可以将其设置为0,这样在输出中就不会显示矢量元素:

> x.str <- capture.output(str(x, vec.len = 0))
> x.str
[1] "List of 3"                            
[2] " $ :List of 2"                        
[3] "  ..$ a: int [1:2, 1:3, 1:4] NULL ..."
[4] "  ..$ b: int [1:3, 1, 1:2] NULL ..."  
[5] " $ :List of 1"                        
[6] "  ..$ c: chr  ..."                    
[7] " $ :List of 2"                        
[8] "  ..$ d: logi [1:3] NULL ..."         
[9] "  ..$ e: logi [1:3] NULL ..."   

将所有内容放在一起,我们可以实现以下功能:

all.equal.structure <- function(x, y) {
    identical(capture.output(str(x, vec.len = 0)),
              capture.output(str(y, vec.len = 0)))
}

> all.equal.structure(x, y)
[1] TRUE
> all.equal.structure(y, z)
[1] FALSE