Need help flattening a list in a specific manner

Hi,

I have a list that looks like below. I want to put the tmp2[[ x ]]$value in the first column, and then put all the 11 items in tmp2[[ x ]]$data into its own columns. So in total, I should have 12 columns. I am not sure how to start with this even. Any help would be really appreciated. Thanks.

sample object below:

tmp2 <- list(list(itemId = "11910220000", value = "00:00 2019-11-22", 
    data = list(3046.2, 3046.2, 658.74, 572.12, 692.02, 647.21, 
        183.25, 189.87, 60, 0, 17.99)), list(itemId = "11910220001", 
    value = "00:01 2019-11-22", data = list(2990.6, 2990.6, 521.92, 
        738.19, 351.78, 538.99, 622.12, 192.6, 25, 0, 0)), list(
    itemId = "11910220002", value = "00:02 2019-11-22", data = list(
        2659.23, 2659.23, 693.09, 492.97, 635.4, 203.96, 432.98, 
        116.46, 84.37, 0, 0)))

I tried

tmp3 <- tmp2 %>%
  map_df(extract,"value")

This gives me a dataframe with a single column with all the values from tmp[[ x ]]$value

When I try

tmp3 <- tmp2 %>%
  map_df(extract,"data")

I get all the values of data in a single column.

Ideal result would give me a single row for each value with it in the first column, then it's data attribute to be in the other 10 columns.

Hi @rbrowne. It would be more easy to handle you problem if you can give out a sample data. For example, post the output of dput(tmp2).

Thank you @raytong for the suggestion

Here's my output for the first 3 items:

list(list(itemId = "11910220000", value = "00:00 2019-11-22", 
    data = list(3046.2, 3046.2, 658.74, 572.12, 692.02, 647.21, 
        183.25, 189.87, 60, 0, 17.99)), list(itemId = "11910220001", 
    value = "00:01 2019-11-22", data = list(2990.6, 2990.6, 521.92, 
        738.19, 351.78, 538.99, 622.12, 192.6, 25, 0, 0)), list(
    itemId = "11910220002", value = "00:02 2019-11-22", data = list(
        2659.23, 2659.23, 693.09, 492.97, 635.4, 203.96, 432.98, 
        116.46, 84.37, 0, 0)))

I tried to follow this SO guide from hrbrmstr but am unable to get it to work.

@rbrowne. Try the follow code see if the result is what you expected.

library(tidyverse)

lst <- list(list(itemId = "11910220000", value = "00:00 2019-11-22", 
                 data = list(3046.2, 3046.2, 658.74, 572.12, 692.02, 647.21, 
                             183.25, 189.87, 60, 0, 17.99)), list(itemId = "11910220001", 
                                                                  value = "00:01 2019-11-22", data = list(2990.6, 2990.6, 521.92, 
                                                                                                          738.19, 351.78, 538.99, 622.12, 192.6, 25, 0, 0)), list(
                                                                                                            itemId = "11910220002", value = "00:02 2019-11-22", data = list(
                                                                                                              2659.23, 2659.23, 693.09, 492.97, 635.4, 203.96, 432.98, 
                                                                                                              116.46, 84.37, 0, 0)))

map_dfr(lst, ~{data.frame(.x$value, t(unlist(.x$data)), stringsAsFactors = FALSE)}) %>%
  `colnames<-`(c("value", paste0("data", 1:11)))
#>              value   data1   data2  data3  data4  data5  data6  data7  data8
#> 1 00:00 2019-11-22 3046.20 3046.20 658.74 572.12 692.02 647.21 183.25 189.87
#> 2 00:01 2019-11-22 2990.60 2990.60 521.92 738.19 351.78 538.99 622.12 192.60
#> 3 00:02 2019-11-22 2659.23 2659.23 693.09 492.97 635.40 203.96 432.98 116.46
#>   data9 data10 data11
#> 1 60.00      0  17.99
#> 2 25.00      0   0.00
#> 3 84.37      0   0.00

Created on 2019-11-24 by the reprex package (v0.3.0)

1 Like

Thank you so much @raytong

Worked. You have been of great help.

If you don't mind, can you explain what ~ does in front of the dataframe argument?

I had been trying to use map_dfr with flatten but was getting nowhere.

@rbrowne. ~ like the shorthand of function. You can see it as function like this.

map_dfr(lst, function(.x){data.frame(.x$value, t(unlist(.x$data)), stringsAsFactors = FALSE)})
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.