Тестировать вложенные списки на идентичную структуру - PullRequest
0 голосов
/ 06 ноября 2018

Скажем, у меня есть несколько сложных, вложенных списков:

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 голосов
/ 06 ноября 2018

Функцией 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...