Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bind_rows to each group of tibble

Consider the following two tibbles:

library(tidyverse)
a <- tibble(time = c(-1, 0), value = c(100, 200))
b <- tibble(id = rep(letters[1:2], each = 3), time = rep(1:3, 2), value = 1:6)

So a and b have the same columns and b has an additional column called id. I want to do the following: group b by id and then add tibble a on top of each group. So the output should look like this:

# A tibble: 10 x 3
   id     time value
   <chr> <int> <int>
 1 a        -1     100
 2 a         0     200
 3 a         1     1
 4 a         2     2
 5 a         3     3
 6 b        -1     100
 7 b         0     200
 8 b         1     4
 9 b         2     5
10 b         3     6

Of course there are multiple workarounds to achieve this (like loops for example). But in my case I have a large number of IDs and a very large number of columns. I would be thankful if anyone could point me towards the direction of a solution within the tidyverse.

Thank you

like image 365
Cettt Avatar asked Jan 27 '23 19:01

Cettt


2 Answers

We can expand the data frame a with id from b and then bind_rows them together.

library(tidyverse)

a2 <- expand(a, id = b$id, nesting(time, value))
b2 <- bind_rows(a2, b) %>% arrange(id, time)
b2
# # A tibble: 10 x 3
#    id     time value
#    <chr> <dbl> <dbl>
#  1 a        -1   100
#  2 a         0   200
#  3 a         1     1
#  4 a         2     2
#  5 a         3     3
#  6 b        -1   100
#  7 b         0   200
#  8 b         1     4
#  9 b         2     5
# 10 b         3     6
like image 159
www Avatar answered Feb 01 '23 07:02

www


split from base R will divide a data frame into a list of subsets based on an index.

b %>%
  split(b[["id"]]) %>%
  lapply(bind_rows, a) %>%
  lapply(select, -"id") %>%
  bind_rows(.id = "id")
# # A tibble: 10 x 3
#    id     time value
#    <chr> <dbl> <dbl>
#  1 a         1     1
#  2 a         2     2
#  3 a         3     3
#  4 a        -1   100
#  5 a         0   200
#  6 b         1     4
#  7 b         2     5
#  8 b         3     6
#  9 b        -1   100
# 10 b         0   200
like image 30
Nathan Werth Avatar answered Feb 01 '23 06:02

Nathan Werth