Как создать подмножество списка, содержащего несколько списков в R, основываясь на имени столбца, и объединить в один список / фрейм данных? - PullRequest
0 голосов
/ 30 мая 2018

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

list1<- list(a= c(1:6),
      b= c(4:9),
      c= c(3:8))
list2<- list(a= c(12:17),
      b= c(10:15),
      c= c(11:16))
list3<- list(a= c(2:7),
      b= c(14:19),
      c= c(9:14))
all<- list (list1, list2, list3)
new_column_names<- c("Block1", "Block2", "Block3")

Я хотел бы поместить все списки в «a» и объединить их в один фрейм данных с именами new_column_names в качестве имен столбцов.Какие-либо предложения?Спасибо!

Ответы [ 5 ]

0 голосов
/ 02 июня 2018

В базе R:

as.data.frame(setNames(lapply(all,`[[`,"a"),new_column_names))
#   Block1 Block2 Block3
# 1      1     12      2
# 2      2     13      3
# 3      3     14      4
# 4      4     15      5
# 5      5     16      6
# 6      6     17      7
0 голосов
/ 30 мая 2018

Вот модифицированная опция, использующая tidyverse

library(tidyverse)
map(all, ~ as_tibble(.x) %>%
               select(a)) %>%
      set_names(new_column_names) %>% 
      bind_rows(.id = 'ind')
# A tibble: 18 x 2
#   ind        a
#   <chr>  <int>
# 1 Block1     1
# 2 Block1     2
# 3 Block1     3
# 4 Block1     4
# 5 Block1     5
# 6 Block1     6
# 7 Block2    12
# 8 Block2    13
# 9 Block2    14
#10 Block2    15
#11 Block2    16
#12 Block2    17
#13 Block3     2
#14 Block3     3
#15 Block3     4
#16 Block3     5
#17 Block3     6
#18 Block3     7

Или использующая map2

map2_df(all, new_column_names,
                 ~ as_tibble(.x) %>% 
                        mutate(ind = .y) %>%
                        select(ind, a))
0 голосов
/ 30 мая 2018

Вы можете попробовать

library(tidyverse)
all %>% 
  flatten() %>%
  keep(names(.) =="a") %>%
  set_names(new_column_names) %>% 
  map(~tibble(a=.x, n=seq_along(.x))) %>% 
  bind_rows(.id = "ind") 
# A tibble: 17 x 3
   ind        a     n
   <chr>  <int> <int>
 1 Block1     1     1
 2 Block1     2     2
 3 Block1     3     3
 4 Block1     4     4
 5 Block1     5     5
 6 Block2    12     1
 7 Block2    13     2
 8 Block2    14     3
 9 Block2    15     4
10 Block2    16     5
11 Block2    17     6
12 Block3     2     1
13 Block3     3     2
14 Block3     4     3
15 Block3     5     4
16 Block3     6     5
17 Block3     7     6

Затем вы можете распространить, например, чтобы получить data.frame

.Last.value %>% 
  spread(ind, a)
# A tibble: 6 x 4
      n Block1 Block2 Block3
  <int>  <int>  <int>  <int>
1     1      1     12      2
2     2      2     13      3
3     3      3     14      4
4     4      4     15      5
5     5      5     16      6
6     6     NA     17      7
0 голосов
/ 30 мая 2018

Если вы хотите data.frame, вам придется сначала сделать векторы a равной длины.Тогда cbind результаты.

res <- lapply(all, `[[`, "a")
n <- max(sapply(res, length))
res <- lapply(res, function(x) if(length(x) < n) c(x, rep(NA, n - length(x))) else x)
res <- do.call(cbind, res)
res <- as.data.frame(res)
res <- setNames(res, new_column_names)
res
#  Block1 Block2 Block3
#1      1     12      2
#2      2     13      3
#3      3     14      4
#4      4     15      5
#5      5     16      6
#6     NA     17      7
0 голосов
/ 30 мая 2018

Вы не можете превратить их в обычный data.frame, потому что эти a-векторы имеют разную длину и data.frame требует, чтобы все столбцы имели одинаковую длину.

Вместо этого вы можете превратить их в длинныеформатированный data.frame с использованием:

stack(setNames(lapply(all, `[[`, "a"), new_column_names))
#    values    ind
# 1       1 Block1
# 2       2 Block1
# 3       3 Block1
# 4       4 Block1
# 5       5 Block1
# 6      12 Block2
# 7      13 Block2
# 8      14 Block2
# 9      15 Block2
# 10     16 Block2
# 11     17 Block2
# 12      2 Block3
# 13      3 Block3
# 14      4 Block3
# 15      5 Block3
# 16      6 Block3
# 17      7 Block3
...