I have a list of list like the following:
alist <- list(
product1 = list(date = seq(from = 0, to = 10, by = 1),
value = seq(from = 100, to = 110, by = 1)),
product2 = list(date = seq(from = 0, to = 15, by = 1),
value = seq(from = 200, to = 215, by = 1))
)
And I need to coerce it to a tibble, where the output should be like it:
tibble(
date = seq(from = 0, to = 15, by = 1),
product1 = c(seq(from = 100, to = 110, by = 1), rep(NA,5)),
product2 = seq(from = 200, to = 215, by = 1),
)
But note that the product1 list is smaller than product2 list.
How can I do it?
1 Like
I love this question! It really shows a place where {purrr} can shine:
library(tidyverse)
# Start
alist <- list(
product1 = list(date = seq(from = 0, to = 10, by = 1),
value = seq(from = 100, to = 110, by = 1)),
product2 = list(date = seq(from = 0, to = 15, by = 1),
value = seq(from = 200, to = 215, by = 1))
)
# Goal
tibble(
date = seq(from = 0, to = 15, by = 1),
product1 = c(seq(from = 100, to = 110, by = 1), rep(NA,5)),
product2 = seq(from = 200, to = 215, by = 1),
)
#> # A tibble: 16 x 3
#> date product1 product2
#> <dbl> <dbl> <dbl>
#> 1 0 100 200
#> 2 1 101 201
#> 3 2 102 202
#> 4 3 103 203
#> 5 4 104 204
#> 6 5 105 205
#> 7 6 106 206
#> 8 7 107 207
#> 9 8 108 208
#> 10 9 109 209
#> 11 10 110 210
#> 12 11 NA 211
#> 13 12 NA 212
#> 14 13 NA 213
#> 15 14 NA 214
#> 16 15 NA 215
# Solution
alist %>%
map(as_tibble) %>%
imap(~as_tibble(.x) %>% transmute(date, !!.y := value)) %>%
reduce(full_join, by = "date")
#> # A tibble: 16 x 3
#> date product1 product2
#> <dbl> <dbl> <dbl>
#> 1 0 100 200
#> 2 1 101 201
#> 3 2 102 202
#> 4 3 103 203
#> 5 4 104 204
#> 6 5 105 205
#> 7 6 106 206
#> 8 7 107 207
#> 9 8 108 208
#> 10 9 109 209
#> 11 10 110 210
#> 12 11 NA 211
#> 13 12 NA 212
#> 14 13 NA 213
#> 15 14 NA 214
#> 16 15 NA 215
Created on 2021-05-21 by the reprex package (v2.0.0)
2 Likes
I have a slightly different solution but similar ideas.
library(tidyverse)
alist <- list(
product1 = list(date = seq(from = 0, to = 10, by = 1),
value = seq(from = 100, to = 110, by = 1)),
product2 = list(date = seq(from = 0, to = 15, by = 1),
value = seq(from = 200, to = 215, by = 1))
)
# This function renames value to a new name
rnf <- function(df, newname){
rename(df, {{newname}}:=value)
}
# alist2 is a list of tibbles now
alist2 <- alist %>% map(as_tibble) %>% map2(names(alist), rnf)
alist2
#> $product1
#> # A tibble: 11 x 2
#> date product1
#> <dbl> <dbl>
#> 1 0 100
#> 2 1 101
#> 3 2 102
#> 4 3 103
#> 5 4 104
#> 6 5 105
#> 7 6 106
#> 8 7 107
#> 9 8 108
#> 10 9 109
#> 11 10 110
#>
#> $product2
#> # A tibble: 16 x 2
#> date product2
#> <dbl> <dbl>
#> 1 0 200
#> 2 1 201
#> 3 2 202
#> 4 3 203
#> 5 4 204
#> 6 5 205
#> 7 6 206
#> 8 7 207
#> 9 8 208
#> 10 9 209
#> 11 10 210
#> 12 11 211
#> 13 12 212
#> 14 13 213
#> 15 14 214
#> 16 15 215
#
alist2 %>% reduce(full_join, by="date")
#> # A tibble: 16 x 3
#> date product1 product2
#> <dbl> <dbl> <dbl>
#> 1 0 100 200
#> 2 1 101 201
#> 3 2 102 202
#> 4 3 103 203
#> 5 4 104 204
#> 6 5 105 205
#> 7 6 106 206
#> 8 7 107 207
#> 9 8 108 208
#> 10 9 109 209
#> 11 10 110 210
#> 12 11 NA 211
#> 13 12 NA 212
#> 14 13 NA 213
#> 15 14 NA 214
#> 16 15 NA 215
Created on 2021-05-21 by the reprex package (v2.0.0)
2 Likes
And I was thinking a bit more about this. You could make a long tibble by stacking the data and then make it wider as follows:
library(tidyverse)
alist <- list(
product1 = list(date = seq(from = 0, to = 10, by = 1),
value = seq(from = 100, to = 110, by = 1)),
product2 = list(date = seq(from = 0, to = 15, by = 1),
value = seq(from = 200, to = 215, by = 1))
)
alist %>%
map(as_tibble) %>%
bind_rows(.id="id") %>%
pivot_wider(names_from="id", values_from="value")
#> # A tibble: 16 x 3
#> date product1 product2
#> <dbl> <dbl> <dbl>
#> 1 0 100 200
#> 2 1 101 201
#> 3 2 102 202
#> 4 3 103 203
#> 5 4 104 204
#> 6 5 105 205
#> 7 6 106 206
#> 8 7 107 207
#> 9 8 108 208
#> 10 9 109 209
#> 11 10 110 210
#> 12 11 NA 211
#> 13 12 NA 212
#> 14 13 NA 213
#> 15 14 NA 214
#> 16 15 NA 215
Created on 2021-05-21 by the reprex package (v2.0.0)
4 Likes
@willmjr if any of these answered your problem, would you mind marking it as a solution? That will help others know this question has been answered.
system
Closed
6
This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.
If you have a query related to it or one of the replies, start a new topic and refer back with a link.