9

我将 JSON 文件转换为具有嵌套列表结构的 data.frame,我想取消嵌套和展平。列表中的一些值是 NULL,unnest 不接受。如果我用只有 NA 值的 data.frame 结构替换 NULL 值,我会得到所需的结果。

下面是我的问题的简化示例。我试图用 NA data.frame 替换 NULL 值,但由于嵌套结构而没有管理。我怎样才能达到预期的效果?

例子

library(tidyr)
input1 <- data.frame(id = c("c", "d", "e"), value = c(7, 8, 9))
input2 <- NULL
input3 <- data.frame(id = c(NA), value = c(NA))

df <- dplyr::tibble(
a = c(1, 2),
b = list(a = input1, c = input2))  
unnest(df)

给出错误“错误:每一列必须是向量列表或数据框列表 [b]”

df2 <- dplyr::tibble(
a = c(1, 2),
b = list(a = input1, c = input3))  
unnest(df2)

给出所需的输出。

4

2 回答 2

17

我们可以map_lglpurrr这里使用。如果您不关心带有 a 的那些行NULL,您可以简单地使用filterand删除它们unnest

library(tidyverse)

df %>% 
  filter(!map_lgl(b, is.null)) %>% 
  unnest() 
#> # A tibble: 3 x 3
#>       a     id value
#>   <dbl> <fctr> <dbl>
#> 1     1      c     7
#> 2     1      d     8
#> 3     1      e     9

如果您想保留这些行,可以在取消嵌套后将它们带回来right_join

df %>% 
  filter(!map_lgl(b, is.null)) %>% 
  unnest() %>% 
  right_join(select(df, a))
#> Joining, by = "a"
#> # A tibble: 4 x 3
#>       a     id value
#>   <dbl> <fctr> <dbl>
#> 1     1      c     7
#> 2     1      d     8
#> 3     1      e     9
#> 4     2   <NA>    NA

数据

input1 <- data.frame(id = c("c", "d", "e"), value = c(7, 8, 9))
input2 <- NULL
input3 <- data.frame(id = c(NA), value = c(NA))

df <- dplyr::tibble(
  a = c(1, 2),
  b = list(a = input1, c = input2)
)  
于 2017-11-10T14:45:40.147 回答
1

正如上面@Frank 所指出的,从tidyr1.0.0 开始,这可以使用keep_empty参数来实现

library(tidyr)

input1 <- data.frame(id = c("c", "d", "e"), value = c(7, 8, 9))
input2 <- NULL

df <- tibble::tibble(
  a = c(1, 2),
  b = list(a = input1, c = input2)
)

unnest(df, cols = b, keep_empty = TRUE)
#> # A tibble: 4 x 3
#>       a id    value
#>   <dbl> <chr> <dbl>
#> 1     1 c         7
#> 2     1 d         8
#> 3     1 e         9
#> 4     2 NA       NA

reprex 包于 2021-09-24 创建(v2.0.1)

于 2021-09-23T23:44:54.870 回答