Using group_split, add a single value to each item in a list for looping and accumulating over

Viewed 85

I have a grouped dataframe using dplyr's group_split function e.g.

mylist <- diamonds %>% group_by(cut, color) %>% group_split

The list items are numbers sequentially. My goal is to eventually map over each item and 'build up' or accumulate a value, e.g. the min price for each.

For example, the first item in mylist is:

mylist[1]
<list_of<
  tbl_df<
    carat  : double
    cut    : ordered<90576>
    color  : ordered<bd2ad>
    clarity: ordered<ecdea>
    depth  : double
    table  : double
    price  : integer
    x      : double
    y      : double
    z      : double
  >
>[1]>
[[1]]
# A tibble: 163 x 10
   carat cut   color clarity depth table price     x     y     z
   <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
 1  0.75 Fair  D     SI2      64.6    57  2848  5.74  5.72  3.7 
 2  0.71 Fair  D     VS2      56.9    65  2858  5.89  5.84  3.34
 3  0.9  Fair  D     SI2      66.9    57  2885  6.02  5.9   3.99
 4  1    Fair  D     SI2      69.3    58  2974  5.96  5.87  4.1 
 5  1.01 Fair  D     SI2      64.6    56  3003  6.31  6.24  4.05
 6  0.73 Fair  D     VS1      66      54  3047  5.56  5.66  3.7 
 7  0.71 Fair  D     VS2      64.7    58  3077  5.61  5.58  3.62
 8  0.91 Fair  D     SI2      62.5    66  3079  6.08  6.01  3.78
 9  0.9  Fair  D     SI2      65.9    59  3205  6     5.95  3.94
10  0.9  Fair  D     SI2      66      58  3205  6     5.97  3.95
# … with 153 more rows

Suppose I would like to add a variable alongside this list item that is the min price for the grouping, is there a way to make mylist[1] contain not just a tbl but also the another item that is the min of price for this group?

In case there's a 'better' way to do what I eventually want to do, what I plan to do with my list is purrr::map over each item and apply a function that takes both the list item tbl and the single numeric value min(price) for the group and then passes the min price through a loop, adding to it on each iteration nrow(tbl) times.

What's the best way to structure mylist given my goal?

2 Answers

We can create a more specific name for our output variable using imap:

mylist %>%
  imap(~ .x %>%
         mutate(!!paste("Min_Price", .y) := reduce(price, min))) %>%
  magrittr::extract(1)

[[1]]
# A tibble: 163 x 11
   carat cut   color clarity depth table price     x     y     z `Min_Price 1`
   <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>         <int>
 1  0.75 Fair  D     SI2      64.6    57  2848  5.74  5.72  3.7            536
 2  0.71 Fair  D     VS2      56.9    65  2858  5.89  5.84  3.34           536
 3  0.9  Fair  D     SI2      66.9    57  2885  6.02  5.9   3.99           536
 4  1    Fair  D     SI2      69.3    58  2974  5.96  5.87  4.1            536
 5  1.01 Fair  D     SI2      64.6    56  3003  6.31  6.24  4.05           536
 6  0.73 Fair  D     VS1      66      54  3047  5.56  5.66  3.7            536
 7  0.71 Fair  D     VS2      64.7    58  3077  5.61  5.58  3.62           536
 8  0.91 Fair  D     SI2      62.5    66  3079  6.08  6.01  3.78           536
 9  0.9  Fair  D     SI2      65.9    59  3205  6     5.95  3.94           536
10  0.9  Fair  D     SI2      66      58  3205  6     5.97  3.95           536
# ... with 153 more rows

Perhaps, we can create a named list by looping over the list

library(purrr)
out <- map(mylist, ~ list(data = ., min_price = min(.$price)))

-checking

> out[[1]]$data
# A tibble: 163 x 10
   carat cut   color clarity depth table price     x     y     z
   <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
 1  0.75 Fair  D     SI2      64.6    57  2848  5.74  5.72  3.7 
 2  0.71 Fair  D     VS2      56.9    65  2858  5.89  5.84  3.34
 3  0.9  Fair  D     SI2      66.9    57  2885  6.02  5.9   3.99
 4  1    Fair  D     SI2      69.3    58  2974  5.96  5.87  4.1 
 5  1.01 Fair  D     SI2      64.6    56  3003  6.31  6.24  4.05
 6  0.73 Fair  D     VS1      66      54  3047  5.56  5.66  3.7 
 7  0.71 Fair  D     VS2      64.7    58  3077  5.61  5.58  3.62
 8  0.91 Fair  D     SI2      62.5    66  3079  6.08  6.01  3.78
 9  0.9  Fair  D     SI2      65.9    59  3205  6     5.95  3.94
10  0.9  Fair  D     SI2      66      58  3205  6     5.97  3.95
# … with 153 more rows
> out[[1]]$min_price
[1] 536
Related