преобразование вложенного списка в невынесенный с накопленной конкатенацией - PullRequest
6 голосов
/ 09 марта 2011

Я хотел бы преобразовать вложенный список следующим образом:

l <- list(A=list(a=list(1),b=list(2)),
          B=list(cd=list(c=list(3,4,5),d=list(6,7,8)),e=list(c(9,10))))

в список

o <- list(A=c(1,2),A.a=1,A.b=2,B=c(3:10),
          B.cd=c(3:8),B.cd.c=c(3:5),B.cd.d=c(6:8),B.e=c(9:10))

На каждом уровне списка значения из вложенных списков должны объединяться.

1 Ответ

7 голосов
/ 09 марта 2011

Ясно, что дело в рекурсивной функции, но получить возвращаемые значения для правильного удаления сложно Вот функция, которая сделает это; имена не совсем правильные, но потом это легко исправить.

unnest <- function(x) {
  if(is.null(names(x))) {
    list(unname(unlist(x)))
  }
  else {
    c(list(all=unname(unlist(x))), do.call(c, lapply(x, unnest)))
  }
}

Выход unnest(l) равен

$all
 [1]  1  2  3  4  5  6  7  8  9 10

$A.all
[1] 1 2

$A.a
[1] 1

$A.b
[1] 2

$B.all
[1]  3  4  5  6  7  8  9 10

$B.cd.all
[1] 3 4 5 6 7 8

$B.cd.c
[1] 3 4 5

$B.cd.d
[1] 6 7 8

$B.e
[1]  9 10

и может быть преобразован в желаемый результат с помощью

out <- unnest(l)
names(out) <- sub("\\.*all", "", names(out))
out[-1]

Чтобы не повторяться, когда есть только один элемент, попробуйте

unnest2 <- function(x) {
  if(is.null(names(x)) | length(x)==1) {
    list(unname(unlist(x)))
  } else {
    c(list(all=unname(unlist(x))), do.call(c, lapply(x, unnest2)))
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...