Assign increasing index per group in grouped dataframe in R

Viewed 113

I have a dataframe/tibble that looks like this:

# A tibble: 15 x 2
# Groups:   id [3]
      id date      
   <int> <date>    
 1     1 1998-02-13
 2     1 1998-02-14
 3     1 1998-02-15
 4     1 1998-02-16
 5     1 1998-02-17
 6     2 1998-02-13
 7     2 1998-02-14
 8     2 1998-02-15
 9     2 1998-02-16
10     2 1998-02-17
11     3 1998-02-13
12     3 1998-02-14
13     3 1998-02-15
14     3 1998-02-16
15     3 1998-02-17

I would like to add a variable "days_before_event" that would count from 1:5 (but this should not be hardcoded and rather be the elments per group). I though about doing something like this

df_long %>% mutate(days_before_event = 1:nrow(.))

where nrow(.) should be the the number of rows per group. This does not work and shows the error

Fehler: Problem with `mutate()` input `days_before_event`.
x Input `days_before_event` can't be recycled to size 5.
i Input `days_before_event` is `1:nrow(.)`.
i Input `days_before_event` must be size 5 or 1, not 15.
i The error occurred in group 1: id = 1.

Any trick on how i can achieve this?

1 Answers

We can use row_number instead of 1:nrow

library(dplyr)
df_long %>% 
    mutate(days_before_event =row_number())

Or using base R, use ave to group over the 'id' and get the sequence (seq_along)

df_long$days_before_event <- with(df_long, ave(seq_along(id),
          id, FUN = seq_along))

The error is because it is a grouped dataset (from the group attribute showed in the printed data), therefore, 1:nrow will get the sequence from 1st to the last row of the entire dataset and not the last row of the group. This creates an imbalance in length and mutate can return only the output having the same length as the original data (or else have to wrap in a list)

Related