Я хотел бы преобразовать список следующим образом:

l <- list(x = c(1, 2), y = c(3, 4, 5))

В тибле, как это:

 Name  Value 
 x      1
 x      2
 y      3
 y      4
 y      5
3
danilinares 20 Сен 2017 в 15:26

3 ответа

Лучший ответ

Я думаю, что нет ничего проще, чем использовать stack - функцию из базы R:

df <- stack(l)

Возвращает вам фрейм данных:

> df
  values ind
1      1   x
2      2   x
3      3   y
4      4   y
5      5   y

Поскольку вы запросили tibble в качестве вывода, вы можете сделать as_tibble(df) (из пакета tibble), чтобы получить его.

Или, точнее, df <- as.tibble(stack(l)).


Другой метод чистого базового R:

df <- data.frame(ind = rep(names(l), lengths(l)), value = unlist(l), row.names = NULL)

Который дает аналогичный результат:

> df
  ind value
1   x     1
2   x     2
3   y     3
4   y     4
5   y     5

row.names = NULL не обязательно нужен, но дает номера строк в качестве имен строк.

8
Jaap 22 Сен 2017 в 07:39

Обновить

Я нашел лучшее решение.

Это работает как в случае простых, так и сложных списков, подобных тому, который я выложил ранее (ниже)

l %>% map_dfr(~ .x %>% as_tibble(), .id = "name")

Дать нам

# A tibble: 5 x 2
  name  value
  <chr> <dbl>
1 x        1.
2 x        2.
3 y        3.
4 y        4.
5 y        5.

==============================================

Оригинальный ответ

Из Тидиверс :

l %>% 
  map(~ as_tibble(.x)) %>% 
  map2(names(.), ~ add_column(.x, Name = rep(.y, nrow(.x)))) %>% 
  bind_rows()

Дать нам

# A tibble: 5 × 2
  value  Name
  <dbl> <chr>
1     1     x
2     2     x
3     3     y
4     4     y
5     5     y

Функция стека из базы R отлично подходит для простых списков, как показал Jaap.

Тем не менее, с более сложными списками, такими как:

l <- list(
  a = list(num = 1:3, let_a = letters[1:3]),
  b = list(num = 101:103, let_b = letters[4:6]),
  c = list()
)

Мы получаем

stack(l)

values ind
1       1   a
2       2   a
3       3   b
4       a   b
5       b   a
6       c   a
7     101   b
8     102   b
9     103   a
10      d   a
11      e   b
12      f   b

Что неправильно.

Решение Tidyverse, показанное выше, прекрасно работает, храня данные из разных элементов вложенного списка отдельно:

# A tibble: 6 × 4
    num   let  Name  lett
  <int> <chr> <chr> <chr>
1     1     a     a  <NA>
2     2     b     a  <NA>
3     3     c     a  <NA>
4   101  <NA>     b     d
5   102  <NA>     b     e
6   103  <NA>     b     f
0
Pablo Cánovas 16 Янв 2019 в 21:47

Мы можем использовать melt из reshape2

library(reshape2)
melt(l)
#   value L1
#1     1  x
#2     2  x
#3     3  y
#4     4  y
#5     5  y
1
akrun 20 Сен 2017 в 15:18