У меня есть вложенный список данных. Его длина составляет 132, а каждый элемент представляет собой список длиной 20. Существует ли быстрый способ преобразовать эту структуру во фрейм данных, содержащий 132 строки и 20 столбцов данных?
Вот некоторые примеры данных для работы:
l <- replicate(
132,
list(sample(letters, 20)),
simplify = FALSE
)
Ответы:
Предполагая, что ваш список списков называется
l
:Выше приведено преобразование всех символьных столбцов в факторы, во избежание этого вы можете добавить параметр в вызов data.frame ():
источник
С
rbind
Edit: Предыдущая версия возвращение
data.frame
изlist
«S вместо векторов (как @IanSudbery указано в комментариях).источник
rbind(your_list)
возвращает матрицу списка 1x32?do.call
передать элементы вyour_list
качестве аргументовrbind
. Это эквивалентrbind(your_list[[1]], your_list[[2]], your_list[[3]], ....., your_list[[length of your_list]])
.your_list
содержали векторы одинакового размера.NULL
имеет длину 0, поэтому он должен потерпеть неудачу.Вы можете использовать
plyr
пакет. Например, вложенный список формытеперь имеет длину 4, и каждый список
l
содержит еще один список длины 3. Теперь вы можете запуститьи должен получить тот же результат, что и в ответе @Marek и @nico.
источник
matrix
подходом.data.frame(t(sapply(mylistlist,c)))
sapply
преобразует его в матрицу.data.frame
преобразует матрицу в кадр данныхисточник
c
играть здесь, один экземпляр данных списка? Ой, подождите, c для конкатенации, верно? Запутаться с использованием @ mnel c. Я также согласен с @dchandler, поэтому правильное использование имен столбцов было очень важно в моем случае использования. Гениальное решение.?c
:Combine Values into a Vector or List
Предположим, ваш список называется
L
,источник
data.frame(Reduce(rbind, list(c('col1','col2'))))
создает фрейм данных с 2 строками, 1 столбцом (я ожидал 1 ряд и 2 столбца)Пакет
data.table
имеет функцию,rbindlist
которая является сверхбыстрой реализациейdo.call(rbind, list(...))
.Это может занять список
lists
,data.frames
или вdata.tables
качестве входных данных.Это возвращает
data.table
наследство отdata.frame
.Если вы действительно хотите преобразовать обратно в data.frame, используйте
as.data.frame(DT)
источник
setDF
теперь позволяет вернуться к data.frame по ссылке.В
tibble
пакете есть функция,enframe()
которая решает эту проблему путем приведения вложенныхlist
объектов к вложеннымtibble
(«аккуратным» фреймам данных) объектам. Вот краткий пример от R для Data Science :Поскольку в вашем списке несколько вложений
l
, вы можете использовать ихunlist(recursive = FALSE)
для удаления ненужных вложений, чтобы получить только один иерархический список и затем перейти кenframe()
. Я использую,tidyr::unnest()
чтобы раскрутить вывод в одноуровневый «аккуратный» фрейм данных, в котором есть два столбца (один для группыname
и один для наблюдений с группамиvalue
). Если вы хотите, чтобы столбцы расширялись, вы можете добавить столбец,add_column()
который повторяет порядок значений 132 раза. Тогда толькоspread()
ценности.источник
В зависимости от структуры ваших списков, есть несколько
tidyverse
опций, которые хорошо работают с списками неравной длины:Вы также можете смешивать векторы и фреймы данных:
источник
X2
нельзя преобразовать из целого в символReshape2 выдает тот же результат, что и в примере с plyr:
выходы:
Если у вас почти не осталось пикселей, вы можете сделать все это в одну строку с помощью recast ().
источник
Этот метод использует
tidyverse
пакет ( purrr ).Список:
Преобразование его во фрейм данных (
tibble
более конкретно):источник
Продолжая ответ @ Marek: если вы хотите избежать превращения строк в факторы, эффективность не является проблемой, попробуйте
источник
Больше ответов, а также сроки в ответе на этот вопрос: Каков наиболее эффективный способ преобразования списка в фрейм данных?
Самый быстрый способ, который не создает информационный фрейм со списками, а не векторами для столбцов, выглядит так (из ответа Мартина Моргана):
источник
Для общего случая глубоко вложенных списков с 3 или более уровнями, подобными тем, которые получены из вложенного JSON:
рассмотрим подход
melt()
к преобразованию вложенного списка в высокий формат:затем,
dcast()
затем, чтобы снова расшириться до аккуратного набора данных, где каждая переменная образует столбец, а каждое наблюдение образует строку:источник
Иногда ваши данные могут быть списком векторов одинаковой длины.
(Внутренние векторы также могут быть списками, но я упрощаю, чтобы их было легче читать).
Затем вы можете сделать следующую модификацию. Помните, что вы можете удалить один уровень за раз:
Теперь используйте ваш любимый метод, упомянутый в других ответах:
источник
Вот что наконец-то сработало для меня:
do.call("rbind", lapply(S1, as.data.frame))
источник
источник
Для параллельного (многоядерного, мультисессионного и т. Д.) Решения, использующего
purrr
семейство решений, используйте:Где
l
список?Для сравнения наиболее эффективных
plan()
вы можете использовать:источник
У меня сработала следующая простая команда:
Ссылка ( Quora answer )
Но это не получится, если неясно, как преобразовать список во фрейм данных:
Примечание : ответ идет к названию вопроса и может пропустить некоторые детали вопроса
источник
Короткий (но, возможно, не самый быстрый) способ сделать это - использовать базу r, поскольку кадр данных - это просто список векторов равной длины . Таким образом, преобразование между вашим входным списком и размером 30 x 132 data.frame будет:
Оттуда мы можем переместить его в матрицу 132 x 30 и преобразовать обратно в массив данных:
Как однострочник:
Имена строк будут довольно раздражающими, но вы всегда можете переименовать их с
rownames(new_df) <- 1:nrow(new_df)
источник
Как насчет использования
map_
функции вместе сfor
циклом? Вот мое решение:где
map_dfr
преобразовать каждый элемент списка в data.frame, а затемrbind
их вместе.В вашем случае, я думаю, это будет:
источник