Reputation: 113
I have a tibble with a list column where each element contains a list of length 2. I have tried to use unlist(), unnest() and flatten() and various other combinations but no luck getting my desired outcome.
A minimal working example is below:
df <- tibble(x = c('A', 'B'),
preds = list(list(Phi = data.frame(time = 1:2, estimate = c('y1', 'y2')),
p = data.frame(time = 1:2, estimate = c('y3', 'y4'))),
list(Phi = data.frame(time = 1:2, estimate = c('y5', 'y6')),
p = data.frame(time = 1:2, estimate = c('y7', 'y8')))))
with an expected outcome:
output <- tibble(x = rep(c('A', 'B'), each = 4),
grp = c(rep(c('Phi', 'p'), each = 2 ), rep(c('Phi', 'p'), each = 2 )),
time = rep(1:2, 4),
estimate = c('y1', 'y2', 'y3', 'y4', 'y5', 'y6', 'y7', 'y8'))
The following code gets me part way and I could easily include the other columns, but its not correct.
df$preds %>% flatten_df()
After a day of googling I'm still stuck. Please point me in some direction.......many thanks!!!
Upvotes: 2
Views: 545
Reputation: 6264
Building on akrun's already good answer, I offer the following.
library(tidyr)
library(dplyr)
df %>%
mutate(
preds = lapply(
preds, lapply, mutate, estimate = as.character(estimate)
) %>%
lapply(bind_rows, .id = "grp")
) %>%
unnest
# # A tibble: 8 x 4
# x grp time estimate
# <chr> <chr> <int> <chr>
# 1 A Phi 1 y1
# 2 A Phi 2 y2
# 3 A p 1 y3
# 4 A p 2 y4
# 5 B Phi 1 y5
# 6 B Phi 2 y6
# 7 B p 1 y7
# 8 B p 2 y8
N.B. The only improvement is the conversion of
estimate
from factor to character. Otherwise, and if this could be addressed in the source data, the map solution by akrun is more concise and easier to reason about.
Upvotes: 1