as_tibble控制扁平化程度
as_tibble control level of flattening
在下面的示例中,我有一个列表,其中一个元素是一个带有子列表的列表。看起来 as_tibble()
在停止之前变平直到列表的第 3 级。能够控制扁平化会很好,这样我就可以在示例的元素 "c"
中保留整个列表和子列表。我怀疑需要 map()
、flatten()
等的某种组合,但无法弄清楚。
问题转载
as_tibble()
returns 2 行,但我真的只想要 1 行,其中一列对应于每个列表元素("a"、"b"、"c").
library(dplyr)
x <- list(a = 1,
b = 2,
c = list(x=list(y=3,
z=4),
xx=NULL))
parsed <- as_tibble(x)
parsed
#> # A tibble: 2 x 3
#> a b c
#> <dbl> <dbl> <list>
#> 1 1. 2. <list [2]>
#> 2 1. 2. <NULL>
parsed[1,]$c
#> $x
#> $x$y
#> [1] 3
#> $x$z
#> [1] 4
parsed[2,]$c
#> $xx
#> NULL
我只取消嵌套第一层的期望行为
parsed <- as_tibble(x)
parsed
#> # A tibble: 1 x 3
#> a b c
#> <dbl> <dbl> <list>
#> 1 1. 2. <list [2]>
parsed[1,]$c
#> $x
#> $x$y
#> [1] 3
#> $x$z
#> [1] 4
#> $xx
#> NULL
这并不优雅,但这是一种方法。
library(purrr)
x <- list(a = 1,
b = 2,
c = list(x=list(y=3,
z=4),
xx=NULL))
# define a function to preserve the list
unnest_one_level <- function(x){
if(is.list(x)) list(x) else x
}
res <- x %>% map_dfr(unnest_one_level)
res
#> # A tibble: 1 x 3
#> a b c
#> <dbl> <dbl> <list>
#> 1 1. 2. <list [2]>
res$c
#> [[1]]
#> [[1]]$x
#> [[1]]$x$y
#> [1] 3
#>
#> [[1]]$x$z
#> [1] 4
#>
#> [[1]]$xx
#> NULL
as.tibble 将重复每列循环每列值,直到它们都具有共享数量的元素。这里是 a
和 b
的长度为 1,但是 c
的长度为 2。所以看起来你真的想把它当作一个长度为 1 的列表,你只需要将它嵌套在一个列表。我认为至少在这种情况下这会满足您的要求。
parsed <- as_tibble(modify_if(x, ~length(.x)>1, list))
在下面的示例中,我有一个列表,其中一个元素是一个带有子列表的列表。看起来 as_tibble()
在停止之前变平直到列表的第 3 级。能够控制扁平化会很好,这样我就可以在示例的元素 "c"
中保留整个列表和子列表。我怀疑需要 map()
、flatten()
等的某种组合,但无法弄清楚。
问题转载
as_tibble()
returns 2 行,但我真的只想要 1 行,其中一列对应于每个列表元素("a"、"b"、"c").
library(dplyr)
x <- list(a = 1,
b = 2,
c = list(x=list(y=3,
z=4),
xx=NULL))
parsed <- as_tibble(x)
parsed
#> # A tibble: 2 x 3
#> a b c
#> <dbl> <dbl> <list>
#> 1 1. 2. <list [2]>
#> 2 1. 2. <NULL>
parsed[1,]$c
#> $x
#> $x$y
#> [1] 3
#> $x$z
#> [1] 4
parsed[2,]$c
#> $xx
#> NULL
我只取消嵌套第一层的期望行为
parsed <- as_tibble(x)
parsed
#> # A tibble: 1 x 3
#> a b c
#> <dbl> <dbl> <list>
#> 1 1. 2. <list [2]>
parsed[1,]$c
#> $x
#> $x$y
#> [1] 3
#> $x$z
#> [1] 4
#> $xx
#> NULL
这并不优雅,但这是一种方法。
library(purrr)
x <- list(a = 1,
b = 2,
c = list(x=list(y=3,
z=4),
xx=NULL))
# define a function to preserve the list
unnest_one_level <- function(x){
if(is.list(x)) list(x) else x
}
res <- x %>% map_dfr(unnest_one_level)
res
#> # A tibble: 1 x 3
#> a b c
#> <dbl> <dbl> <list>
#> 1 1. 2. <list [2]>
res$c
#> [[1]]
#> [[1]]$x
#> [[1]]$x$y
#> [1] 3
#>
#> [[1]]$x$z
#> [1] 4
#>
#> [[1]]$xx
#> NULL
as.tibble 将重复每列循环每列值,直到它们都具有共享数量的元素。这里是 a
和 b
的长度为 1,但是 c
的长度为 2。所以看起来你真的想把它当作一个长度为 1 的列表,你只需要将它嵌套在一个列表。我认为至少在这种情况下这会满足您的要求。
parsed <- as_tibble(modify_if(x, ~length(.x)>1, list))