Home > Mobile >  Build list of all values in group and apply to entire group
Build list of all values in group and apply to entire group

Time:12-22

I have a dataframe like the below:

x <- tibble(id = c(1,1,1,2,2,2),
            val = c(1,3,5,7,9,11)
            )

I would like to group_by each id, then apply a list/vector of all the vals in each group to every member of that group. The result would be a dataframe like that below.

x_out <- tibble(id = c(1,1,1,2,2,2),
                    val = c(1,3,5,7,9,11),
                    group_vals = list(c(1,3,5),c(1,3,5),c(1,3,5),
                                c(7,9,11),c(7,9,11),c(7,9,11))
               )

How can I do this, since functions like summarize only return a single value for the entire group?

CodePudding user response:

out <- x %>%
  group_by(id) %>%
  mutate(group_vals = list(val)) %>%
  ungroup()
out
# # A tibble: 6 x 3
#      id   val group_vals
#   <dbl> <dbl> <list>    
# 1     1     1 <dbl [3]> 
# 2     1     3 <dbl [3]> 
# 3     1     5 <dbl [3]> 
# 4     2     7 <dbl [3]> 
# 5     2     9 <dbl [3]> 
# 6     2    11 <dbl [3]> 

We can see what the group_vals looks like with:

str(out)
# tibble [6 x 3] (S3: tbl_df/tbl/data.frame)
#  $ id        : num [1:6] 1 1 1 2 2 2
#  $ val       : num [1:6] 1 3 5 7 9 11
#  $ group_vals:List of 6
#   ..$ : num [1:3] 1 3 5
#   ..$ : num [1:3] 1 3 5
#   ..$ : num [1:3] 1 3 5
#   ..$ : num [1:3] 7 9 11
#   ..$ : num [1:3] 7 9 11
#   ..$ : num [1:3] 7 9 11

Verification, using your x_out definition above:

identical(out, tibble(id = c(1,1,1,2,2,2),
                    val = c(1,3,5,7,9,11),
                    group_vals = list(c(1,3,5),c(1,3,5),c(1,3,5),
                                c(7,9,11),c(7,9,11),c(7,9,11))
               ))
# [1] TRUE

CodePudding user response:

another option, using left_join and nest

library(tidyverse)

left_join(x, nest(x, group_vals = val), by = "id")
#> # A tibble: 6 × 3
#>      id   val group_vals      
#>   <dbl> <dbl> <list>          
#> 1     1     1 <tibble [3 × 1]>
#> 2     1     3 <tibble [3 × 1]>
#> 3     1     5 <tibble [3 × 1]>
#> 4     2     7 <tibble [3 × 1]>
#> 5     2     9 <tibble [3 × 1]>
#> 6     2    11 <tibble [3 × 1]>

CodePudding user response:

A data.table option

> setDT(x)[, group_vals := .(list(val)), id][]
   id val group_vals
1:  1   1      1,3,5
2:  1   3      1,3,5
3:  1   5      1,3,5
4:  2   7    7, 9,11
5:  2   9    7, 9,11
6:  2  11    7, 9,11
  • Related