R: исключение нерекурсивных именованных вложенных списков - PullRequest
1 голос
/ 17 июня 2020

Функция relist() (по умолчанию) не переопределяет список, если список не был свернут рекурсивно. Например,

> my_list=list(a=list(aa=c(1,2),ab=2),b=list(ba=1,bb=2))
> flat=unlist(as.relistable(my_list),recursive=FALSE)
Warning message:
In unlist.relistable(x, recursive, use.names) :
  relist() requires recursively unlisted objects.

>relist(flat)
$a
$a$aa
$a$aa[[1]]
[1] 1 2

$a$aa[[2]]
[1] 2

$a$ab
$a$ab[[1]]
[1] 1

$b
$b$ba
$b$ba[[1]]
[1] 2

$b$bb
$b$bb[[1]]
NULL

Я дал частичный ответ и, похоже, работает, но есть ли лучший и полный способ сделать это?

Ответы [ 2 ]

1 голос
/ 17 июня 2020

С вашим не рекурсивным частным списком вы можете снова создать unlist и использовать сохраненный скелет для relist.

relist(unlist(flat), attr(flat,"skeleton"))
#$a
#$a$aa
#[1] 1 2
#
#$a$ab
#[1] 2
#
#
#$b
#$b$ba
#[1] 1
#
#$b$bb
#[1] 2
#
#
#attr(,"class")
#[1] "relistable" "list"      
0 голосов
/ 17 июня 2020

Кажется, это работает и обрабатывает рекурсивный вывод unlist(), который не является полностью рекурсивным (не нарушает массивы или матрицы)

my_relist <- function(x){
    y=list()
    x=as.list(x)
    for (name in names(x)){
        split=strsplit(name,'.',fixed=TRUE)[[1]]
        char='y'
        for (str in split){
            char=paste(char,'$',str,sep="")
        }
    char=paste(char,'= x[[name]]',sep="")
    eval(parse(text=char))
    }
    return(y)
}
...