如何将具有不规则子列表的列表变成数据框?

时间:2018-10-07 16:12:16

标签: r list nested-lists

我正在通过Facebook API来获取商业见解,而返回的数据格式是嵌套列表。我已经将数据简化为一个列表列表。级别1的数据是一致的。级别2的数据始终包含在名为“操作”的列表中,但是在该子列表中的项目数变化的范围内是不规则的。如果没有针对该观察的操作,则actions子列表不存在。

我想将整个内容展平到一个数据框中,以使列的总补全表示第2级“操作”子列表中包含的所有可能项目。如果操作中不存在某些内容,则会插入NA

我更喜欢使用purrr软件包。

示例数据:

 my_list <- list(list(objective = "CONVERSIONS",
      impressions = "4318", actions = list(list(action_device = "other", 
                                                action_type = "page_engagement", value = "2"), list(action_device = "other", 
                                                                                                    action_type = "post_engagement", value = "2"), list(action_device = "other", 
                                                                                                                                                        action_type = "post_reaction", value = "1"), list(action_device = "other", 
                                                                                                                                                                                                          action_type = "video_view", value = "1"), list(action_device = "desktop", 
                                                                                                                                                                                                                                                         action_type = "landing_page_view", value = "1"), list(
                                                                                                                                                                                                                                                           action_device = "desktop", action_type = "link_click", 
                                                                                                                                                                                                                                                           value = "1"), list(action_device = "desktop", action_type = "page_engagement", 
                                                                                                                                                                                                                                                                              value = "18"), list(action_device = "desktop", action_type = "post_engagement", 
                                                                                                                                                                                                                                                                                                  value = "18"), list(action_device = "desktop", action_type = "video_view", 
                                                                                                                                                                                                                                                                                                                      value = "17"), list(action_device = "iphone", action_type = "post", 
                                                                                                                                                                                                                                                                                                                                          value = "1"), list(action_device = "iphone", action_type = "landing_page_view", 
                                                                                                                                                                                                                                                                                                                                                             value = "27"), list(action_device = "iphone", action_type = "link_click", 
                                                                                                                                                                                                                                                                                                                                                                                 value = "30"), list(action_device = "iphone", action_type = "page_engagement", 
                                                                                                                                                                                                                                                                                                                                                                                                     value = "580"), list(action_device = "iphone", action_type = "post_engagement", 
                                                                                                                                                                                                                                                                                                                                                                                                                          value = "580"), list(action_device = "iphone", action_type = "post_reaction", 
                                                                                                                                                                                                                                                                                                                                                                                                                                               value = "6"), list(action_device = "iphone", action_type = "video_view", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  value = "543"), list(action_device = "ipad", action_type = "landing_page_view", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       value = "2"), list(action_device = "ipad", action_type = "link_click", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          value = "2"), list(action_device = "ipad", action_type = "page_engagement", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             value = "29"), list(action_device = "ipad", action_type = "post_engagement", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 value = "29"), list(action_device = "ipad", action_type = "video_view", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     value = "27"), list(action_device = "android_smartphone", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         action_type = "landing_page_view", value = "11"), list(
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           action_device = "android_smartphone", action_type = "link_click", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           value = "12"), list(action_device = "android_smartphone", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               action_type = "page_engagement", value = "222"), list(
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 action_device = "android_smartphone", action_type = "post_engagement", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 value = "222"), list(action_device = "android_smartphone", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      action_type = "post_reaction", value = "9"), list(action_device = "android_smartphone", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        action_type = "video_view", value = "201"), list(action_device = "android_tablet", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         action_type = "landing_page_view", value = "1"), list(
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           action_device = "android_tablet", action_type = "link_click", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           value = "1"), list(action_device = "android_tablet", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              action_type = "page_engagement", value = "7"), list(action_device = "android_tablet", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  action_type = "post_engagement", value = "7"), list(action_device = "android_tablet", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      action_type = "post_reaction", value = "1"), list(action_device = "android_tablet", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        action_type = "video_view", value = "5")), date_start = "2018-09-23", 
      date_stop = "2018-09-23"), list(objective = "CONVERSIONS",
                                      impressions = "8", 
                                      date_start = "2018-09-23", date_stop = "2018-09-23"), list(objective = "CONVERSIONS", 
                                        impressions = "75", actions = list(list(action_device = "desktop", 
                                                                                action_type = "page_engagement", value = "2"), list(action_device = "desktop", 
                                                                                                                                    action_type = "post_engagement", value = "2"), list(action_device = "desktop", 
                                                                                                                                                                                        action_type = "video_view", value = "2"), list(action_device = "iphone", 
                                                                                                                                                                                                                                       action_type = "page_engagement", value = "12"), list(
                                                                                                                                                                                                                                         action_device = "iphone", action_type = "post_engagement", 
                                                                                                                                                                                                                                         value = "12"), list(action_device = "iphone", action_type = "video_view", 
                                                                                                                                                                                                                                                             value = "12"), list(action_device = "ipad", action_type = "page_engagement", 
                                                                                                                                                                                                                                                                                 value = "5"), list(action_device = "ipad", action_type = "post_engagement", 
                                                                                                                                                                                                                                                                                                    value = "5"), list(action_device = "ipad", action_type = "video_view", 
                                                                                                                                                                                                                                                                                                                       value = "5"), list(action_device = "android_smartphone", 
                                                                                                                                                                                                                                                                                                                                          action_type = "page_engagement", value = "3"), list(action_device = "android_smartphone", 
                                                                                                                                                                                                                                                                                                                                                                                              action_type = "post_engagement", value = "3"), list(action_device = "android_smartphone", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                  action_type = "video_view", value = "3")), date_start = "2018-09-23", 
                                        date_stop = "2018-09-23"), list(objective = "CONVERSIONS",
                                                                        impressions = "54", 
                                                                        actions = list(list(action_device = "iphone", action_type = "page_engagement", 
                                                                                            value = "5"), list(action_device = "iphone", action_type = "post_engagement", 
                                                                                                               value = "5"), list(action_device = "iphone", action_type = "video_view", 
                                                                                                                                  value = "5"), list(action_device = "android_smartphone", 
                                                                                                                                                     action_type = "page_engagement", value = "2"), list(action_device = "android_smartphone", 
                                                                                                                                                                                                         action_type = "post_engagement", value = "2"), list(action_device = "android_smartphone", 
                                                                                                                                                                                                                                                             action_type = "video_view", value = "2")), date_start = "2018-09-23", 
                                                                        date_stop = "2018-09-23"))

1 个答案:

答案 0 :(得分:1)

这项工作吗?

library(tidyverse)
nested_df <- map_dfr(my_list, ~modify_at(.,"actions",compose(list,bind_rows)))
# # A tibble: 4 x 5
#   objective   impressions actions           date_start date_stop 
#   <chr>       <chr>       <list>            <chr>      <chr>     
# 1 CONVERSIONS 4318        <tibble [33 x 3]> 2018-09-23 2018-09-23
# 2 CONVERSIONS 8           <NULL>            2018-09-23 2018-09-23
# 3 CONVERSIONS 75          <tibble [12 x 3]> 2018-09-23 2018-09-23
# 4 CONVERSIONS 54          <tibble [6 x 3]>  2018-09-23 2018-09-23

我们看到在某些没有actions的元素中,您可以轻松地删除这些行, 否则,如果您希望操作列为NA,则可以执行以下操作:

missing_actions <- lengths(nested_df$actions) == 0
nested_df$actions[missing_actions] <- 
  replicate(sum(missing_actions),
            tibble(action_device = NA, action_type = NA, value = NA),F)
nested_df

# # A tibble: 4 x 5
#   objective   impressions actions           date_start date_stop 
#   <chr>       <chr>       <list>            <chr>      <chr>     
# 1 CONVERSIONS 4318        <tibble [33 x 3]> 2018-09-23 2018-09-23
# 2 CONVERSIONS 8           <tibble [1 x 3]>  2018-09-23 2018-09-23
# 3 CONVERSIONS 75          <tibble [12 x 3]> 2018-09-23 2018-09-23
# 4 CONVERSIONS 54          <tibble [6 x 3]>  2018-09-23 2018-09-23

unnest(nested_df)
# # A tibble: 52 x 7
#    objective   impressions date_start date_stop  action_device action_type       value
#    <chr>       <chr>       <chr>      <chr>      <chr>         <chr>             <chr>
#  1 CONVERSIONS 4318        2018-09-23 2018-09-23 other         page_engagement   2    
#  2 CONVERSIONS 4318        2018-09-23 2018-09-23 other         post_engagement   2    
#  3 CONVERSIONS 4318        2018-09-23 2018-09-23 other         post_reaction     1    
#  4 CONVERSIONS 4318        2018-09-23 2018-09-23 other         video_view        1    
#  5 CONVERSIONS 4318        2018-09-23 2018-09-23 desktop       landing_page_view 1    
#  6 CONVERSIONS 4318        2018-09-23 2018-09-23 desktop       link_click        1    
#  7 CONVERSIONS 4318        2018-09-23 2018-09-23 desktop       page_engagement   18   
#  8 CONVERSIONS 4318        2018-09-23 2018-09-23 desktop       post_engagement   18   
#  9 CONVERSIONS 4318        2018-09-23 2018-09-23 desktop       video_view        17   
# 10 CONVERSIONS 4318        2018-09-23 2018-09-23 iphone        post              1    
# # ... with 42 more rows