#r
#r
Вопрос:
У меня есть список, содержащий ряд других списков, каждый из которых содержит разное количество символьных векторов с разным количеством элементов. Я хочу создать фрейм данных, в котором каждый список был бы представлен в виде строки, а каждый вектор символов в этом списке был бы столбцом. Если символьный вектор содержит > 1 элемента, элементы будут объединены и разделены с помощью знака » «, чтобы их можно было сохранить как одну строку. Данные выглядят следующим образом:
fruits <- list(
list(c("orange"), c("pear")),
list(c("pear", "orange")),
list(c("lemon", "apple"),
c("pear"),
c("grape"),
c("apple"))
)
Ожидаемый результат выглядит следующим образом:
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"))
Нет ограничений на количество символьных векторов, которые могут содержаться в списке, поэтому решение должно динамически создавать столбцы, что приводит к df, где количество столбцов равно длине списка, содержащего наибольшее количество символьных векторов.
Ответ №1:
Для каждого списка в fruits
вы можете создать фрейм данных в одну строку и связать данные.
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
Ответ №2:
Это немного запутанно, но вот один из способов
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
или другая стратегия
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
Но на самом деле вам нужно либо построить каждый столбец или строку из вашего списка, а затем объединить их вместе.
Ответ №3:
Другой подход, который преобразует список в data.frame с помощью rrapply::rrapply
, а затем преобразует его в требуемый формат с помощью 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