Search code examples
rpurrr

How to append the name of a sublist vector as a named element within the vector


I have a list that contains web-traffic details.

In the process of rectangling the lists, I'd like to append a value to each vector in the named sublists which is the actual name of the sublist vector.

If I use this for example:

test_list %>% 
  map_depth(2, \(x) append(x, names(x)))

... I end up adding all the vector element names, whereas I want to append an element name of "campaign_type" with either the value "manual_campaign" or "google_ads_campaign" since those are the only 2 names for those sublist vectors.

Successfully the first sublist would have these elements:

  • campaign_id : NA
  • campaign_name : '(organic)'
  • ...
  • marketing_tactic : NA
  • campaign_type : "manual_campaign"

I've been using purrr and the map family for rectangling so either base R or tidyverse is welcome.

Thanks.

Reprex data:

test_list <- structure(list(list(manual_campaign = list(campaign_id = NA_character_, 
    campaign_name = "(organic)", source = "bing", medium = "organic", 
    term = "(not provided)", content = "(not set)", source_platform = NA_character_, 
    creative_format = NA_character_, marketing_tactic = NA_character_), 
    google_ads_campaign = list(NULL, NULL, NULL, NULL, NULL, 
        NULL)), list(manual_campaign = list(campaign_id = NA_character_, 
    campaign_name = "(referral)", source = "Google", medium = "My Campaign", 
    term = "(not set)", content = "(not set)", source_platform = NA_character_, 
    creative_format = NA_character_, marketing_tactic = NA_character_), 
    google_ads_campaign = list(customer_id = "1111", account_name = "My Account", 
        campaign_id = "2222", campaign_name = "My Campaign Name", 
        ad_group_id = "3333", ad_group_name = "My Adgroup"))))```


Solution

  • Here is another approach that allows to include the node list names directly when unnesting the list to a data.frame using the option how = "bind" in rrapply() from package rrapply (extension of base rapply()):

    rrapply::rrapply(
      test_list, 
      condition = Negate(is.null),      ## skip NULLs
      how = "bind",                     ## bind to wide data.frame
      options = list(namecols = TRUE)   ## include list names
    )
    
    #>   L1                  L2 campaign_id    campaign_name source      medium
    #> 1  1     manual_campaign        <NA>        (organic)   bing     organic
    #> 2  2     manual_campaign        <NA>       (referral) Google My Campaign
    #> 3  2 google_ads_campaign        2222 My Campaign Name   <NA>        <NA>
    #>             term   content source_platform creative_format marketing_tactic
    #> 1 (not provided) (not set)            <NA>            <NA>             <NA>
    #> 2      (not set) (not set)            <NA>            <NA>             <NA>
    #> 3           <NA>      <NA>            <NA>            <NA>             <NA>
    #>   customer_id account_name ad_group_id ad_group_name
    #> 1        <NA>         <NA>        <NA>          <NA>
    #> 2        <NA>         <NA>        <NA>          <NA>
    #> 3        1111   My Account        3333    My Adgroup