Transformar uma lista de listas em dataframe
Eu tenho uma lista contendo várias outras listas, cada uma das quais contendo vários números de vetores de caracteres, com vários números de elementos. Eu quero criar um dataframe onde cada lista seria representada como uma linha e cada vetor de caractere dentro dessa lista seria uma coluna. Onde o vetor de caracteres tem> 1 elemento, os elementos seriam concatenados e separados usando um sinal "+", para que pudessem ser armazenados como uma string. Os dados são assim:
fruits <- list(
list(c("orange"), c("pear")),
list(c("pear", "orange")),
list(c("lemon", "apple"),
c("pear"),
c("grape"),
c("apple"))
)
A saída esperada é assim:
fruits_df <- data.frame(col1 = c("orange", "pear + orange", "lemon + apple"),
col2 = c("pear", NA, "pear"),
col3 = c(NA, NA, "grape"),
col4 = c(NA, NA, "apple"))
Não há limite para o número de vetores de caracteres que podem estar contidos em uma lista, então a solução precisa criar colunas dinamicamente, levando a um df onde o número de colunas é igual ao comprimento da lista contendo o maior número de caracteres vetores.
Respostas
Para cada lista, fruitsvocê pode criar um dataframe de uma linha e vincular os dados.
dplyr::bind_rows(lapply(fruits, function(x) as.data.frame(t(sapply(x,
function(y) paste0(y, collapse = "+"))))))
# V1 V2 V3 V4
#1 orange pear <NA> <NA>
#2 pear+orange <NA> <NA> <NA>
#3 lemon+apple pear grape apple
Isso é um pouco confuso, mas aqui está uma maneira
cols <- lapply(fruits, function(x) sapply(x, paste, collapse=" + "))
ncols <- max(lengths(cols))
dd <- do.call("rbind.data.frame", lapply(cols, function(x) {length(x) <- ncols; x}))
names(dd) <- paste0("col", 1:ncol(dd))
dd
# col1 col2 col3 col4
# 1 orange pear <NA> <NA>
# 2 pear + orange <NA> <NA> <NA>
# 3 lemon + apple pear grape apple
ou outra estratégia
ncols <- max(lengths(fruits))
dd <- data.frame(lapply(seq.int(ncols), function(x) sapply(fruits, function(y) paste(unlist(y[x]), collapse=" + "))))
names(dd) <- paste0("col", 1:ncols)
dd
Mas realmente você precisa construir cada coluna ou linha de sua lista e então combiná-las.
Outra abordagem que funde a lista em um data.frame usando rrapply::rrapplye, em seguida, a converte no formato necessário usando data.table::dcast:
library(rrapply)
library(data.table)
## melt to long data.frame
long <- rrapply(fruits, f = paste, how = "melt", collapse = " + ")
## cast to wide data.table
setDT(long)
dcast(long[, .(L1, L2, value = unlist(value))], L1 ~ L2)[, !"L1"]
#> ..1 ..2 ..3 ..4
#> 1: orange pear <NA> <NA>
#> 2: pear + orange <NA> <NA> <NA>
#> 3: lemon + apple pear grape apple