Search code examples
rgroupinglag

Lagged function within group


I would like to write code to compute within each group, sum of lagged differences as shown in the table below:

ID  x rank  U   R   Required Output Value
1   1   1   U1  R1  -
1   1   2   U2  R2  R2-U1
1   1   3   U3  R3  (R3-U2) + (R3-U1)
1   1   4   U4  R4  (R4-U3) + (R4-U2) + (R4-U1)
1   0   5   U5  R5  R5
1   0   6   U6  R6  R6
1   0   7   U7  R7  R7
2   1   1   U8  R8  -
2   1   2   U9  R9  R9-U8
2   1   3   U10 R10 (R10-U9) + (R10 - U8)
2   1   4   U11 R11 (R11-U10) + (R11 - U9) + (R11 - U8)
3   1   1   U12 R12 -
3   0   2   U13 R13 R13
3   0   3   U14 R14 R14

ID is the unique group identifier. x is a bool and depending on its value the required output is either sum of difference with previous values or same period value. "rank" is a rank ordering column and the maximum rank can vary within each group. "U" and "R" are the main columns of interest.

To give a numerical example, I need the following:

ID  x rank  U   R   Required Output Value
1   1   1   10  7   -
1   1   2   9   11  1
1   1   3   10  10  1 + 0 = 1
1   1   4   11  13  3+4+3 = 10
1   0   5   7   8   8
1   0   6   8   8   8
1   0   7   5   7   7
2   1   1   3   2   -
2   1   2   9   15  12
2   1   3   13  14  16
2   1   4   1   14  17
3   1   1   12  1   -
3   0   2   14  9   9
3   0   3   1   11  11

R code to generate this table:

ID = c(rep(1,7),rep(2,4),rep(3,3))
x = c(rep(1,4),rep(0,3),rep(1,5),rep(0,2))
rank = c(1:7,1:4,1:3)
U = c(10,9,10,11,7,8,5,3,9,13,1,12,14,1)
R = c(7,11,10,13,8,8,7,2,15,14,14,1,9,11)
dat = cbind(ID,x,rank,U,R)
colnames(dat)=c("ID","x","rank","U","R")

Solution

  • Here's a tidyverse solution:

    library(dplyr)
    library(tidyr)
    
    dat %>%
      as_tibble() %>%
      group_by(ID) %>%
      mutate(output = ifelse(x, lag(rank) * R - lag(cumsum(U)), R))
    

    Result:

    # A tibble: 14 x 6
    # Groups:   ID [3]
          ID     x  rank     U     R output
       <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>
     1     1     1     1    10     7     NA
     2     1     1     2     9    11      1
     3     1     1     3    10    10      1
     4     1     1     4    11    13     10
     5     1     0     5     7     8      8
     6     1     0     6     8     8      8
     7     1     0     7     5     7      7
     8     2     1     1     3     2     NA
     9     2     1     2     9    15     12
    10     2     1     3    13    14     16
    11     2     1     4     1    14     17
    12     3     1     1    12     1     NA
    13     3     0     2    14     9      9
    14     3     0     3     1    11     11