dan*_*res 3 r list purrr tidyverse tibble
我想转换这样的列表:
l <- list(x = c(1, 2), y = c(3, 4, 5))
Run Code Online (Sandbox Code Playgroud)
像这样的一个小组:
Name Value
x 1
x 2
y 3
y 4
y 5
Run Code Online (Sandbox Code Playgroud)
我认为没有什么比使用stack基础R中的-function 更容易了:
df <- stack(l)
Run Code Online (Sandbox Code Playgroud)
给你一个数据帧:
Run Code Online (Sandbox Code Playgroud)> df values ind 1 1 x 2 2 x 3 3 y 4 4 y 5 5 y
因为你要求tibble输出,你可以as_tibble(df)(从tibble-package)得到它.
或者更直接地:df <- as.tibble(stack(l)).
另一个纯基R方法:
df <- data.frame(ind = rep(names(l), lengths(l)), value = unlist(l), row.names = NULL)
Run Code Online (Sandbox Code Playgroud)
这给出了类似的结果:
Run Code Online (Sandbox Code Playgroud)> df ind value 1 x 1 2 x 2 3 y 3 4 y 4 5 y 5
该row.names = NULL不是必需的,但给rownumbers作为rownames.
我找到了更好的解决方案。
\n\n这适用于简单和复杂的列表,就像我之前发布的列表(如下)
\n\nl %>% map_dfr(~ .x %>% as_tibble(), .id = "name")\nRun Code Online (Sandbox Code Playgroud)\n\n给我们
\n\n# A tibble: 5 x 2\n name value\n <chr> <dbl>\n1 x 1.\n2 x 2.\n3 y 3.\n4 y 4.\n5 y 5.\nRun Code Online (Sandbox Code Playgroud)\n\n来自tidyverse:
\n\nl %>% \n map(~ as_tibble(.x)) %>% \n map2(names(.), ~ add_column(.x, Name = rep(.y, nrow(.x)))) %>% \n bind_rows()\nRun Code Online (Sandbox Code Playgroud)\n\n给我们
\n\n# A tibble: 5 \xc3\x97 2\n value Name\n <dbl> <chr>\n1 1 x\n2 2 x\n3 3 y\n4 4 y\n5 5 y\nRun Code Online (Sandbox Code Playgroud)\n\n正如 Jaap 所示,R 基础的 stack 函数非常适合简单列表。
\n\n但是,对于更复杂的列表,例如:
\n\nl <- list(\n a = list(num = 1:3, let_a = letters[1:3]),\n b = list(num = 101:103, let_b = letters[4:6]),\n c = list()\n)\nRun Code Online (Sandbox Code Playgroud)\n\n我们得到
\n\nstack(l)\n\nvalues ind\n1 1 a\n2 2 a\n3 3 b\n4 a b\n5 b a\n6 c a\n7 101 b\n8 102 b\n9 103 a\n10 d a\n11 e b\n12 f b\nRun Code Online (Sandbox Code Playgroud)\n\n这是错误的。
\n\n上面显示的 tidyverse 解决方案工作正常,将来自嵌套列表的不同元素的数据分开:
\n\n# A tibble: 6 \xc3\x97 4\n num let Name lett\n <int> <chr> <chr> <chr>\n1 1 a a <NA>\n2 2 b a <NA>\n3 3 c a <NA>\n4 101 <NA> b d\n5 102 <NA> b e\n6 103 <NA> b f\nRun Code Online (Sandbox Code Playgroud)\n