使用列表名称作为一列中的值列表到 tibble
List into tibble using list names as values in one column
我想像这样转换列表:
l <- list(x = c(1, 2), y = c(3, 4, 5))
变成这样的小标题:
Name Value
x 1
x 2
y 3
y 4
y 5
我认为没有什么比使用基础 R:
中的 stack
函数更容易的了
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
,但会提供行号作为行名。
我们可以使用 melt
来自 reshape2
library(reshape2)
melt(l)
# value L1
#1 1 x
#2 2 x
#3 3 y
#4 4 y
#5 5 y
更新
我找到了更好的解决方案。
无论是简单列表还是复杂列表,如我之前发布的列表(下方),这都适用
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.
============================================= =
原回答
来自 tidyverse:
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
如 Jaap 所示,基于 R 的堆栈函数非常适合简单列表。
但是,对于更复杂的列表,例如:
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
我想像这样转换列表:
l <- list(x = c(1, 2), y = c(3, 4, 5))
变成这样的小标题:
Name Value
x 1
x 2
y 3
y 4
y 5
我认为没有什么比使用基础 R:
中的stack
函数更容易的了
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
,但会提供行号作为行名。
我们可以使用 melt
来自 reshape2
library(reshape2)
melt(l)
# value L1
#1 1 x
#2 2 x
#3 3 y
#4 4 y
#5 5 y
更新
我找到了更好的解决方案。
无论是简单列表还是复杂列表,如我之前发布的列表(下方),这都适用
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.
============================================= =
原回答
来自 tidyverse:
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
如 Jaap 所示,基于 R 的堆栈函数非常适合简单列表。
但是,对于更复杂的列表,例如:
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