Problem: With a data frame like:
df <- data.frame('ID'  = c(1,   1,   1,   1,   2,   2,   2,   2),
                 'UD'  = c(0,   5,   10,  15,  0,   0,   10,  15),
                 'LD'  = c(5,   10,  15,  20,  5,   10,  15,  20),
                 'VAL' = c(1.2, 3.6, 5.7, 8.0, 5.2, 5.6, 8.7, 3.1))
for each ID group, the value of LD must match the value of UD on the next row down. So df[6, 2] should be 5, not 0.
I've been trying to write a function that can move through a data frame like this one and make that kind of correction. I think I've gotten close with the following, but the edited value is being overwritten as rollapply reassembles its outputs.   
fix <- function(df) {
  df2 <- by(df, as.factor(df$ID), FUN = function(x) {
    rollapply(x, width = 2, FUN = function(y) {
      y[2, 2] <- ifelse(y[2, 2] != y[1, 3], y[1, 3], y[2, 2])
      print(y) #  test
      return(y)
      }, by.column = FALSE)
    print('x:') # test
    print(x)    # test
    return(x)
  })
  out <- do.call('rbind', df2)
  return(out)
  }
Is there a way to fix this, or a better alternative approach to the issue?
edit - expected output:
df2 <- data.frame('ID'  = c(1,   1,   1,   1,   2,   2,   2,   2),
                  'UD'  = c(0,   5,   10,  15,  0,   5,   10,  15),
                  'LD'  = c(5,   10,  15,  20,  5,   10,  15,  20),
                  'VAL' = c(1.2, 3.6, 5.7, 8.0, 5.2, 5.6, 8.7, 3.1))
 
     
    