R - Create new variable using the difference between lagged values

Viewed 23

The problem: I need to create a new variable (eventWindowTime) in R that is based on data from two columns - obstacle present (1=yes,0=no) and timeOnTask (assessed continuously).

The dataset: I have data that was continuously collected (to the fractional seconds) from several participants as they performed a task. At various points, participants encountered one or more obstacles. I would like to create obstacle event windows that range from -5s (5 s before the obstacle) to +20s (20 s after the obstacle).

Additional challenges:

  • Some event windows are overlapping
  • Some timestamps have multiple measurements (so I can't rep values -5 to 20 relative to the first obstaclePresent == 1)

Things I've tried: The way I would typically approach this is to use ifelse or case_when functions with lag() to:

  • set eventWindowTime to 0 when obstaclePresent == 1 && lag(obstaclePresent == 0)
  • set eventWindow Time to increment the lagged eventWindowTime value by the difference in timeOnTask values across the two rows when obstaclePresent == 1 && lag(obstaclePresent == 1).
  • then backfill the negative seconds in a second step.

However, R does not seem to hold the lagged values in memory and I keep getting a "Error in vec_slice(): ! x must be a vector, not NULL." error.

Here's a small subset of code and a file which can be used to reproduce the problem:

mre <- data.frame(Sub = rep(1, 41), Time = c(723.2, 723.2, 723.3, 723.3, 723.3, 723.4, 723.4, 723.5, 723.5, 723.6, 723.6, 723.6, 723.7, 723.7, 723.7, 723.8, 723.9, 723.9, 723.9, 724, 724, 724, 724, 724.1, 724.1, 724.2, 724.2, 724.2, 724.3, 724.3, 724.3, 724.4, 724.4, 724.5, 724.5, 724.6, 724.6, 724.6, 724.7, 724.7, 724.8), obstaclePresent = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1))

mre$obstacleEventWindow <- case_when(
  mre$obstaclePresent != lag(mre$obstaclePresent,1) & mre$obstaclePresent == 0 ~ 0,
  mre$obstaclePresent == lag(mre$obstaclePresent,1) ~ lag(mre$obstacleEventWindow) + mre$newTime - lag(mre$newTime,1),
  TRUE ~ 0
)

To be clear, I understand that the case_when() statement is self-referencing. I've worked with other programs where a column is populated on the fly, and you can reference lagged cells without issue. That isn't working here, but I'm at a loss with respect to what to do instead.

0 Answers
Related