r语言 - 如何将具有不规则子列表的列表列表转换为数据框?



我正在通过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"))

这行得通吗?

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

最新更新