Во-первых, значения NULL
не имеют значения, потому что rbind(NULL, NULL, ..., A, B, C, ...)
точно так же, как rbind(A, B, C, ...)
.
Во-вторых, структура вашего списка имеет значение.Если ваш вложенный список так же прост, как ваш пример, то ответ также прост.Приведенный ниже код может решить эту проблему:
# This list is the same as your example
test <- list(
list(NULL, NULL),
list(data.frame(name = c("jack", "jim", "joe", "jon"),
value = c("10", "12", "13", "14")),
data.frame(name = c("jacky", "jane", "juanita", "julia"),
value = c("11", "9", "10", "14"))),
list(data.frame(name = c("adam", "ashley", "arnold", "avery", "arthur"),
value = c("6", "7", "11", "12", "11")))
)
# This function rbinds the dataframes inside a list
ls_rbind <- function(ls_of_df) do.call(rbind, ls_of_df)
# Applying "ls_rbind" to each of your child lists creates a list, each of whose elements is either a NULL or a dataframe
# Applying "ls_rbind" again to the result list gives you a dataframe you want
result_df <- ls_rbind(lapply(test, ls_rbind))
Однако, если ваш вложенный список на самом деле более сложный, то вам может понадобиться более общий способ его обработки.Например, каждый дочерний список может быть одним из следующих элементов:
- Элемент, не являющийся списком, т. Е. Кадр данных, или
NULL
- Список, который также может содержать списки,фреймы данных или
NULL
s
В этом случае рекурсии могут быть полезны.Рассмотрим следующий код:
# These two lines complicate the list structure
test[[4]] <- test
test[[1]][[3]] <- test
recr_ls_rbind <- function(ls_of_ls) {
are_lists <- lapply(ls_of_ls, class) == "list"
# Any child lists will be recursively evaluated. "part1" is always a list
part1 <- lapply(ls_of_ls[are_lists], recr_ls_rbind)
# Applying the above function "ls_rbind" to all non-list child items and then coerce the result into a list.
part2 <- list(ls_rbind(ls_of_ls[!are_lists]))
# Put part1 and part2 into the same list and apply "ls_rbind" to it.
ls_rbind(c(part1, part2))
}
result_df <- recr_ls_rbind(test)