Объедините вложенные списки различных списков в список фреймов данных

у меня есть большое количество списков, каждый из которых состоит из многих вложенных списков. Каждый список содержит вложенный список, в котором каждый вложенный список будет иметь одинаковое имя и количество наблюдений в разных списках.

вот простой пример данных:

score <- list(Bob = list(c('1'), ('0')), Jane = list(c('1'), ('2'), ('4'), ('2')))
comments <- list(Bob = list(c('AAA'), ('BBB')), Jane = list(c('ZZZ'), ('XXX'), ('YYY'), ('QQQ')))

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

my.list.Bob
score   comments  
1    AAA  
0    BBB

my.list.Jane  
score   comments  
1    ZZZ  
2    XXX  
4    YYY  
2    QQQ  

2 ответов


вот один из способов для вас. Если у вас есть все списки в глобальной среде, вы можете сделать следующее. Во-первых, вы создаете список со всеми списками, которые у вас есть. Затем вы используете transpose(), что позволяет создать список для каждого человека (например, Список для Боба со счетом и комментарии). В каждом списке у вас есть комментарии и оценка как вложенные списки в этом случае. Вы хотите распаковать их в каждом списке. По этой причине, вы можете использовать rapply2() по rawr в. Наконец, вы создаете фрейм данных для каждого списка.

library(magrittr)
library(purrr)
library(rawr) #devtools::install_github('raredd/rawr')

score <- list(Bob = list(c('1'), ('0')), Jane = list(c('1'), ('2'), ('4'), ('2')))
comments <- list(Bob = list(c('AAA'), ('BBB')), Jane = list(c('ZZZ'), ('XXX'), ('YYY'), ('QQQ')))

# Get all objects in the global environment and create a list.
mylist <- mget(ls(pattern =  ".*"))

purrr::transpose(mylist) %>%
rapply2(unlist, classes = "list") %>%
lapply(as.data.frame, stringsAsFactors = FALSE)

$Bob
  comments score
1      AAA     1
2      BBB     0

$Jane
  comments score
1      ZZZ     1
2      XXX     2
3      YYY     4
4      QQQ     2

решение с использованием tidyverse. Идея состоит в том, чтобы использовать map2 цикл через каждый элемент из двух списков, используйте map_dfr и as_data_frame для создания фрейма данных, а затем использовать bind_cols для объединения каждого фрейма данных.

library(tidyverse)

map2(score, comments, function(x, y){
  X <- map_dfr(x, as_data_frame)
  Y <- map_dfr(y, as_data_frame)
  dat <- bind_cols(X, Y) %>%
    set_names(c("score", "comments"))
})
# $Bob
# # A tibble: 2 x 2
#   score comments
#   <chr> <chr>   
# 1 1     AAA     
# 2 0     BBB     
# 
# $Jane
# # A tibble: 4 x 2
#   score comments
#   <chr> <chr>   
# 1 1     ZZZ     
# 2 2     XXX     
# 3 4     YYY     
# 4 2     QQQ