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 val
s 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