is there a simple way to unlist a list and keep the names of one level as a new variable?
Working example:
# Input list
my_list <- list(Ticker1 = list(date = seq.Date(as.Date('2021-01-01'), as.Date('2021-01-10'), by = 'day'), Value = 1:10),
Ticker2 = list(date = seq.Date(as.Date('2021-01-01'), as.Date('2021-01-10'), by = 'day'), Value = 11:20),
Ticker3 = list(date = seq.Date(as.Date('2021-01-01'), as.Date('2021-01-10'), by = 'day'), Value = 21:30))
# Desired data frame
my_df_goal <- as.data.frame(list(Ticker = c(rep("Ticker1", 10), rep("Ticker2", 10), rep("Ticker3", 10)),
date = rep(seq.Date(as.Date('2021-01-01'), as.Date('2021-01-10'), by = 'day'), 3),
Value = 1:30))
There are similar questions regarding unlisting on stackoverflow, but I wasn't able to solve my problem.
One way would probably be
my_df <- as.data.frame(rlist::list.flatten(my_list))
# Same result:
my_df2 <- as.data.frame(unlist(my_list,recursive = F))
#Edit: just noticed that you do not need to unlist first to get the same result:
my_df3 <- as.data.frame(my_list)
and then try to extract the Ticker from the new variable name. But I hope there is an easier solution.
I also tried my_df4 <- reshape2::melt(my_list)
, but this is not helpful. I have a feeling that the purrr
package may have this functionality, but I am not familiar with the package.
I am happy about any help!
Thanks a lot
CodePudding user response:
One way:
library(tidyverse)
my_list %>%
enframe() %>%
unnest_wider(value) %>%
unnest(cols = c(date, Value))
# A tibble: 30 x 3
name date Value
<chr> <date> <int>
1 Ticker1 2021-01-01 1
2 Ticker1 2021-01-02 2
3 Ticker1 2021-01-03 3
4 Ticker1 2021-01-04 4
5 Ticker1 2021-01-05 5
6 Ticker1 2021-01-06 6
7 Ticker1 2021-01-07 7
8 Ticker1 2021-01-08 8
9 Ticker1 2021-01-09 9
10 Ticker1 2021-01-10 10
# ... with 20 more rows
CodePudding user response:
dplyr
s bind_rows
should do the trick:
library(dplyr)
bind_rows(my_list, .id = "Ticker")
This returns
# A tibble: 30 x 3
Ticker date Value
<chr> <date> <int>
1 Ticker1 2021-01-01 1
2 Ticker1 2021-01-02 2
3 Ticker1 2021-01-03 3
4 Ticker1 2021-01-04 4
5 Ticker1 2021-01-05 5
6 Ticker1 2021-01-06 6
7 Ticker1 2021-01-07 7
8 Ticker1 2021-01-08 8
9 Ticker1 2021-01-09 9
10 Ticker1 2021-01-10 10
# ... with 20 more rows
CodePudding user response:
Here's a way using lapply
combined with some dplyr
operations.
library(tidyverse)
do.call(rbind, lapply(my_list, data.frame)) %>%
rownames_to_column("Ticker") %>%
mutate(Ticker = gsub("\\..*$", "", Ticker))
Ticker date Value
1 Ticker1 2021-01-01 1
2 Ticker1 2021-01-02 2
3 Ticker1 2021-01-03 3
4 Ticker1 2021-01-04 4
5 Ticker1 2021-01-05 5
6 Ticker1 2021-01-06 6
...