转换具有不同数量元素的嵌套数据框
Transforming a nested data frame with varying number of elements
我有一个数据框,其中包含一列嵌套数据框,其中包含 1 或 2 列和 n 行。它看起来像下面示例中的 df:
'data.frame': 3 obs. of 2 variables:
$ vector:List of 3
..$ : chr "p1"
..$ : chr "p2"
..$ : chr "p3"
$ lists :List of 3
..$ :'data.frame': 2 obs. of 2 variables:
.. ..$ n1: Factor w/ 2 levels "a","b": 1 2
.. ..$ n2: Factor w/ 2 levels "1","2": 1 2
..$ :'data.frame': 1 obs. of 1 variable:
.. ..$ n1: Factor w/ 1 level "d": 1
..$ :'data.frame': 1 obs. of 2 variables:
.. ..$ n1: Factor w/ 1 level "e": 1
.. ..$ n2: Factor w/ 1 level "3": 1
df 可以像这样重新创建:
v <- c("p1", "p2", "p3")
l <- list(data.frame(n1 = c("a", "b"), n2 = c("1", "2")), data.frame(n1 = "d"), data.frame(n1 = "e", n2 = "3"))
df <- as.data.frame(cbind(v, l))
我想将其转换为如下所示的数据框:
[v] [n1] [n2]
p1 a 1
p1 b 2
p2 d NA
p3 e 3
- n1 和 n2 在不同的列中
- 如果第i行的数据框有n行,第i行的向量元素要重复n次
- 如果n1或n2中没有内容,应该有一个NA
我试过使用 tidyr::unnest 但出现以下错误
unnest(df)
Error: All nested columns must have the same number of elements.
有没有人知道如何以所需格式转换数据框?
使用purrr::pmap_df
,在df
的每一行中,我们将v
和l
组合成一个数据帧,然后将所有数据帧组合成一个单个数据框。
library(tidyverse)
pmap_df(df, function(v,l) {
data.frame(v,l)
})
v n1 n2
1 p1 a 1
2 p1 b 2
3 p2 d <NA>
4 p3 e 3
使用 dplyr
和 tidyr
的解决方案。 suppressWarnings
不是必需的。因为你创建数据框的时候,有因子列,suppressWarnings
是为了抑制合并因子时的警告信息。
library(dplyr)
library(tidyr)
df1 <- suppressWarnings(df %>%
mutate(v = unlist(.$v)) %>%
unnest())
df1
# v n1 n2
# 1 p1 a 1
# 2 p1 b 2
# 3 p2 d <NA>
# 4 p3 e 3
这将避免按行操作,如果您有很多行,这将很重要。
library(data.table)
rbindlist(df$l, fill = T, id = 'row')[, v := df$v[row]][]
# row n1 n2 v
#1: 1 a 1 p1
#2: 1 b 2 p1
#3: 2 d NA p2
#4: 3 e 3 p3
我有一个数据框,其中包含一列嵌套数据框,其中包含 1 或 2 列和 n 行。它看起来像下面示例中的 df:
'data.frame': 3 obs. of 2 variables:
$ vector:List of 3
..$ : chr "p1"
..$ : chr "p2"
..$ : chr "p3"
$ lists :List of 3
..$ :'data.frame': 2 obs. of 2 variables:
.. ..$ n1: Factor w/ 2 levels "a","b": 1 2
.. ..$ n2: Factor w/ 2 levels "1","2": 1 2
..$ :'data.frame': 1 obs. of 1 variable:
.. ..$ n1: Factor w/ 1 level "d": 1
..$ :'data.frame': 1 obs. of 2 variables:
.. ..$ n1: Factor w/ 1 level "e": 1
.. ..$ n2: Factor w/ 1 level "3": 1
df 可以像这样重新创建:
v <- c("p1", "p2", "p3")
l <- list(data.frame(n1 = c("a", "b"), n2 = c("1", "2")), data.frame(n1 = "d"), data.frame(n1 = "e", n2 = "3"))
df <- as.data.frame(cbind(v, l))
我想将其转换为如下所示的数据框:
[v] [n1] [n2]
p1 a 1
p1 b 2
p2 d NA
p3 e 3
- n1 和 n2 在不同的列中
- 如果第i行的数据框有n行,第i行的向量元素要重复n次
- 如果n1或n2中没有内容,应该有一个NA
我试过使用 tidyr::unnest 但出现以下错误
unnest(df)
Error: All nested columns must have the same number of elements.
有没有人知道如何以所需格式转换数据框?
使用purrr::pmap_df
,在df
的每一行中,我们将v
和l
组合成一个数据帧,然后将所有数据帧组合成一个单个数据框。
library(tidyverse)
pmap_df(df, function(v,l) {
data.frame(v,l)
})
v n1 n2 1 p1 a 1 2 p1 b 2 3 p2 d <NA> 4 p3 e 3
使用 dplyr
和 tidyr
的解决方案。 suppressWarnings
不是必需的。因为你创建数据框的时候,有因子列,suppressWarnings
是为了抑制合并因子时的警告信息。
library(dplyr)
library(tidyr)
df1 <- suppressWarnings(df %>%
mutate(v = unlist(.$v)) %>%
unnest())
df1
# v n1 n2
# 1 p1 a 1
# 2 p1 b 2
# 3 p2 d <NA>
# 4 p3 e 3
这将避免按行操作,如果您有很多行,这将很重要。
library(data.table)
rbindlist(df$l, fill = T, id = 'row')[, v := df$v[row]][]
# row n1 n2 v
#1: 1 a 1 p1
#2: 1 b 2 p1
#3: 2 d NA p2
#4: 3 e 3 p3