代码之家  ›  专栏  ›  技术社区  ›  DeduciveR

如何将包含不规则子列表的列表转换为数据帧?

  •  0
  • DeduciveR  · 技术社区  · 6 年前

    我通过Facebook的API获取商业信息,返回的数据格式是嵌套列表。我已经将数据简化为一个列表。一级数据是一致的。级别2的数据总是包含在名为“actions”的列表中,但由于子列表中的项数不同,因此是不规则的。如果没有针对该观察的操作,那么 actions 子列表不存在。

    我想将整个内容展平到一个数据帧中,以便列的总补码表示级别2“actions”子列表中包含的所有可能项。如果行动中没有什么东西,那么 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 回复  |  直到 6 年前
        1
  •  2
  •   moodymudskipper    6 年前

    这样行吗?

    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