取消嵌套数据框并用 NA 填充新行

问题描述

假设我有一个嵌套的 df,我想取消嵌套列:

df <- tibble::tribble(
    ~x,~y,~nestdf,1,2,tibble::tibble(a=1:2,b=3:4),3,4,tibble::tibble(a=3:5,b=5:7)
)
tidyr::unnest(df,nestdf)

#      x     y     a     b
#  <dbl> <dbl> <int> <int>
#1     1     2     1     3
#2     1     2     2     4
#3     3     4     3     5
#4     3     4     4     6
#5     3     4     5     7

结果扩展了 xy 列以匹配 nestdf 的维度,新行使用现有值。但是,我希望新行包含 NA,如下所示:

#      x     y     a     b
#  <dbl> <dbl> <int> <int>
#1     1     2     1     3
#2    NA    NA     2     4
#3     3     4     3     5
#4    NA    NA     4     6
#5    NA    NA     5     7

是否可以使用 unnest 执行此操作?每个组的第一行或最后一行都可以保留为非 NA,我不介意。

解决方法

一种方法是将重复项更改为 NA

df1 <- tidyr::unnest(df,nestdf) 
cols <- c('x','y')
df1[duplicated(df1[cols]),cols] <- NA
df1

#      x     y     a     b
#  <dbl> <dbl> <int> <int>
#1     1     2     1     3
#2    NA    NA     2     4
#3     3     4     3     5
#4    NA    NA     4     6
#5    NA    NA     5     7

如果 xy 列中的值可以重复,您可以创建一个行号来唯一地标识它们 -

library(dplyr)
library(tidyr)

df1 <- df %>% mutate(row = row_number()) %>% unnest(nestdf)
cols <- c('x','y','row')
df1[duplicated(df1[cols]),cols] <- NA
df1 <- select(df1,-row)
,

重复行,并与嵌套列表列的 unnest 绑定:

nr <- sapply(df$nestdf,nrow) - 1
cbind(
  df[rep(rbind(seq_along(nr),NA),rbind(1,nr)),c("x","y")],unnest(df["nestdf"],cols=everything())
)

#   x  y a b
#1  1  2 1 3
#2 NA NA 2 4
#3  3  4 3 5
#4 NA NA 4 6
#5 NA NA 5 7
,

您可以先将 xy 转换为列表:

library(tidyverse)

df <- tibble::tribble(
  ~x,~y,~nestdf,1,2,tibble::tibble(a=1:2,b=3:4),3,4,tibble::tibble(a=3:5,b=5:7)
)

df %>%
  mutate_at(vars(x:y),~map2(.,nestdf,~.x[seq(nrow(.y))])) %>%
  unnest(everything())

# A tibble: 5 x 4
#x     y     a     b
#<dbl> <dbl> <int> <int>
#  1     1     2     1     3
#2    NA    NA     2     4
#3     3     4     3     5
#4    NA    NA     4     6
#5    NA    NA     5     7