Function to create a lagged variable.

lagvar(x, id, obs, day, time, data, lag=1)

Arguments

x

argument to specify the variable to be lagged.

id

optional argument to specify a subject id variable.

obs

optional argument that indicates the observation number of the values specified via the x argument.

day

optional argument to specify a day number variable.

time

optional argument to specify a variable that indicates the actual date and time of the observations.

data

optional data frame that contains the variables specified above.

lag

scalar specifying the lag (default is 1). Can also be a vector with multiple lag values that are permitted. See ‘Details’.

Details

The function can be used to create a lagged version of the variable specified via the x argument.

The (optional) id argument is used to specify a subject id variable. If not specified, all observations are assumed to come from the same subject. If the dataset includes multiple subjects, then this variable needs to be specified so that observations are not lagged across subjects.

The (optional) obs argument is used to specify a variable that indicates the observation number of the values specified via the x argument. There should not be repeated values of obs (within the same subject, in case the dataset includes multiple subjects). If not specified, then consecutive observations from the same subject are assumed to be one lag apart.

The (optional) day variable is used to specify a day number variable. If not specified, then values of the variable to be lagged are allowed to be lagged across days (in case there are multiple observation days). If the day variable is specified, then lagged values across different days are not allowed (i.e., are set to missing).

The (optional) time variable is used to specify a variable that indicates the actual date and time of the observations. Ideally this should be a POSIXct variable, but can also be numeric as long as this variable indicates the passage of time (e.g., in minutes) since some reference point (e.g., the first observation of each subject).

The lag argument is used to specify the number of lags (i.e., the lagged value of the variable at a particular observation number \(t\) is the value of the variable observed at observation number \(t - lag\)). If no lagged value is available at observation number \(t - lag\) (either because the dataset does not include that observation number or the value at that observation number is missing), then the lagged value will be missing.

One can also specify multiple values for the lag argument (usually a consecutive range, such as 1:3). In that case, the function will find the lagged value with the smallest lag and also indicate the lag of each lagged value. See ‘Examples’.

Value

If lag is a single number, the function returns a vector with the lagged values (that will typically be added back to the data frame as a new variable).

If a time variable is also specified, then the function returns a data frame with elements xl for the lagged values and timelag for the time lag between the observations (in seconds if the time variable was of class POSIXct and otherwise in the units of the time variable).

If multiple values are specified for lag, the function returns a data frame with elements xl for the lagged values and lag for the lag of those values (and again timelag if a time variable was also specified).

Author

Wolfgang Viechtbauer wvb@wvbauer.com

Examples

# illustrative dataset (10 beeps for 2 days for 2 subjects)
dat <- structure(list(subject = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), dayno = c(1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), beep =
c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L,
17L, 18L, 19L, 20L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L,
14L, 15L, 16L, 17L, 18L, 19L, 20L), beeptime = structure(c(1571551380,
1571558400, 1571563080, 1571567640, 1571573760, 1571580900, 1571582820,
1571590860, 1571595360, 1571599320, 1571640120, 1571643180, 1571650680,
1571656140, 1571660760, 1571666100, 1571671080, 1571675280, 1571681880,
1571688480, 1571812380, 1571815080, 1571823360, 1571828220, 1571832780,
1571838900, 1571842320, 1571851380, 1571854380, 1571859600, 1571900280,
1571903700, 1571910060, 1571915340, 1571922360, 1571925660, 1571931360,
1571938680, 1571943960, 1571948160), class = c("POSIXct", "POSIXt")),
relaxed = c(2, 6, 6, 6, 5, 6, 6, 6, NA, 5, 1, NA, 6, 6, 6, NA, 6, 6, 6, 4,
2, 7, 7, NA, NA, 7, 7, 1, 7, 6, NA, 7, 6, NA, NA, NA, 7, 4, 7, 7)),
row.names = c(NA, 40L), class = "data.frame")
dat
#>    subject dayno beep            beeptime relaxed
#> 1        1     1    1 2019-10-20 08:03:00       2
#> 2        1     1    2 2019-10-20 10:00:00       6
#> 3        1     1    3 2019-10-20 11:18:00       6
#> 4        1     1    4 2019-10-20 12:34:00       6
#> 5        1     1    5 2019-10-20 14:16:00       5
#> 6        1     1    6 2019-10-20 16:15:00       6
#> 7        1     1    7 2019-10-20 16:47:00       6
#> 8        1     1    8 2019-10-20 19:01:00       6
#> 9        1     1    9 2019-10-20 20:16:00      NA
#> 10       1     1   10 2019-10-20 21:22:00       5
#> 11       1     2   11 2019-10-21 08:42:00       1
#> 12       1     2   12 2019-10-21 09:33:00      NA
#> 13       1     2   13 2019-10-21 11:38:00       6
#> 14       1     2   14 2019-10-21 13:09:00       6
#> 15       1     2   15 2019-10-21 14:26:00       6
#> 16       1     2   16 2019-10-21 15:55:00      NA
#> 17       1     2   17 2019-10-21 17:18:00       6
#> 18       1     2   18 2019-10-21 18:28:00       6
#> 19       1     2   19 2019-10-21 20:18:00       6
#> 20       1     2   20 2019-10-21 22:08:00       4
#> 21       2     1    1 2019-10-23 08:33:00       2
#> 22       2     1    2 2019-10-23 09:18:00       7
#> 23       2     1    3 2019-10-23 11:36:00       7
#> 24       2     1    4 2019-10-23 12:57:00      NA
#> 25       2     1    5 2019-10-23 14:13:00      NA
#> 26       2     1    6 2019-10-23 15:55:00       7
#> 27       2     1    7 2019-10-23 16:52:00       7
#> 28       2     1    8 2019-10-23 19:23:00       1
#> 29       2     1    9 2019-10-23 20:13:00       7
#> 30       2     1   10 2019-10-23 21:40:00       6
#> 31       2     2   11 2019-10-24 08:58:00      NA
#> 32       2     2   12 2019-10-24 09:55:00       7
#> 33       2     2   13 2019-10-24 11:41:00       6
#> 34       2     2   14 2019-10-24 13:09:00      NA
#> 35       2     2   15 2019-10-24 15:06:00      NA
#> 36       2     2   16 2019-10-24 16:01:00      NA
#> 37       2     2   17 2019-10-24 17:36:00       7
#> 38       2     2   18 2019-10-24 19:38:00       4
#> 39       2     2   19 2019-10-24 21:06:00       7
#> 40       2     2   20 2019-10-24 22:16:00       7

# lag the relaxed variable
dat$relaxed_lag <- lagvar(relaxed, id=subject, obs=beep, data=dat)
dat
#>    subject dayno beep            beeptime relaxed relaxed_lag
#> 1        1     1    1 2019-10-20 08:03:00       2          NA
#> 2        1     1    2 2019-10-20 10:00:00       6           2
#> 3        1     1    3 2019-10-20 11:18:00       6           6
#> 4        1     1    4 2019-10-20 12:34:00       6           6
#> 5        1     1    5 2019-10-20 14:16:00       5           6
#> 6        1     1    6 2019-10-20 16:15:00       6           5
#> 7        1     1    7 2019-10-20 16:47:00       6           6
#> 8        1     1    8 2019-10-20 19:01:00       6           6
#> 9        1     1    9 2019-10-20 20:16:00      NA           6
#> 10       1     1   10 2019-10-20 21:22:00       5          NA
#> 11       1     2   11 2019-10-21 08:42:00       1           5
#> 12       1     2   12 2019-10-21 09:33:00      NA           1
#> 13       1     2   13 2019-10-21 11:38:00       6          NA
#> 14       1     2   14 2019-10-21 13:09:00       6           6
#> 15       1     2   15 2019-10-21 14:26:00       6           6
#> 16       1     2   16 2019-10-21 15:55:00      NA           6
#> 17       1     2   17 2019-10-21 17:18:00       6          NA
#> 18       1     2   18 2019-10-21 18:28:00       6           6
#> 19       1     2   19 2019-10-21 20:18:00       6           6
#> 20       1     2   20 2019-10-21 22:08:00       4           6
#> 21       2     1    1 2019-10-23 08:33:00       2          NA
#> 22       2     1    2 2019-10-23 09:18:00       7           2
#> 23       2     1    3 2019-10-23 11:36:00       7           7
#> 24       2     1    4 2019-10-23 12:57:00      NA           7
#> 25       2     1    5 2019-10-23 14:13:00      NA          NA
#> 26       2     1    6 2019-10-23 15:55:00       7          NA
#> 27       2     1    7 2019-10-23 16:52:00       7           7
#> 28       2     1    8 2019-10-23 19:23:00       1           7
#> 29       2     1    9 2019-10-23 20:13:00       7           1
#> 30       2     1   10 2019-10-23 21:40:00       6           7
#> 31       2     2   11 2019-10-24 08:58:00      NA           6
#> 32       2     2   12 2019-10-24 09:55:00       7          NA
#> 33       2     2   13 2019-10-24 11:41:00       6           7
#> 34       2     2   14 2019-10-24 13:09:00      NA           6
#> 35       2     2   15 2019-10-24 15:06:00      NA          NA
#> 36       2     2   16 2019-10-24 16:01:00      NA          NA
#> 37       2     2   17 2019-10-24 17:36:00       7          NA
#> 38       2     2   18 2019-10-24 19:38:00       4           7
#> 39       2     2   19 2019-10-24 21:06:00       7           4
#> 40       2     2   20 2019-10-24 22:16:00       7           7

# in this example, consecutive observations from the same subject are each
# one lag apart, so one can leave out the 'obs' (i.e., 'beep') argument here
dat$relaxed_lag <- lagvar(relaxed, id=subject, data=dat)
dat
#>    subject dayno beep            beeptime relaxed relaxed_lag
#> 1        1     1    1 2019-10-20 08:03:00       2          NA
#> 2        1     1    2 2019-10-20 10:00:00       6           2
#> 3        1     1    3 2019-10-20 11:18:00       6           6
#> 4        1     1    4 2019-10-20 12:34:00       6           6
#> 5        1     1    5 2019-10-20 14:16:00       5           6
#> 6        1     1    6 2019-10-20 16:15:00       6           5
#> 7        1     1    7 2019-10-20 16:47:00       6           6
#> 8        1     1    8 2019-10-20 19:01:00       6           6
#> 9        1     1    9 2019-10-20 20:16:00      NA           6
#> 10       1     1   10 2019-10-20 21:22:00       5          NA
#> 11       1     2   11 2019-10-21 08:42:00       1           5
#> 12       1     2   12 2019-10-21 09:33:00      NA           1
#> 13       1     2   13 2019-10-21 11:38:00       6          NA
#> 14       1     2   14 2019-10-21 13:09:00       6           6
#> 15       1     2   15 2019-10-21 14:26:00       6           6
#> 16       1     2   16 2019-10-21 15:55:00      NA           6
#> 17       1     2   17 2019-10-21 17:18:00       6          NA
#> 18       1     2   18 2019-10-21 18:28:00       6           6
#> 19       1     2   19 2019-10-21 20:18:00       6           6
#> 20       1     2   20 2019-10-21 22:08:00       4           6
#> 21       2     1    1 2019-10-23 08:33:00       2          NA
#> 22       2     1    2 2019-10-23 09:18:00       7           2
#> 23       2     1    3 2019-10-23 11:36:00       7           7
#> 24       2     1    4 2019-10-23 12:57:00      NA           7
#> 25       2     1    5 2019-10-23 14:13:00      NA          NA
#> 26       2     1    6 2019-10-23 15:55:00       7          NA
#> 27       2     1    7 2019-10-23 16:52:00       7           7
#> 28       2     1    8 2019-10-23 19:23:00       1           7
#> 29       2     1    9 2019-10-23 20:13:00       7           1
#> 30       2     1   10 2019-10-23 21:40:00       6           7
#> 31       2     2   11 2019-10-24 08:58:00      NA           6
#> 32       2     2   12 2019-10-24 09:55:00       7          NA
#> 33       2     2   13 2019-10-24 11:41:00       6           7
#> 34       2     2   14 2019-10-24 13:09:00      NA           6
#> 35       2     2   15 2019-10-24 15:06:00      NA          NA
#> 36       2     2   16 2019-10-24 16:01:00      NA          NA
#> 37       2     2   17 2019-10-24 17:36:00       7          NA
#> 38       2     2   18 2019-10-24 19:38:00       4           7
#> 39       2     2   19 2019-10-24 21:06:00       7           4
#> 40       2     2   20 2019-10-24 22:16:00       7           7

# but this also allows lagged values across days (e.g., the value '5' from
# beep 10 on day 1 becomes the lagged value for beep 11 on day 2); this can
# be avoided by specifying the day variable
dat$relaxed_lag <- lagvar(relaxed, id=subject, obs=beep, day=dayno, data=dat)
dat
#>    subject dayno beep            beeptime relaxed relaxed_lag
#> 1        1     1    1 2019-10-20 08:03:00       2          NA
#> 2        1     1    2 2019-10-20 10:00:00       6           2
#> 3        1     1    3 2019-10-20 11:18:00       6           6
#> 4        1     1    4 2019-10-20 12:34:00       6           6
#> 5        1     1    5 2019-10-20 14:16:00       5           6
#> 6        1     1    6 2019-10-20 16:15:00       6           5
#> 7        1     1    7 2019-10-20 16:47:00       6           6
#> 8        1     1    8 2019-10-20 19:01:00       6           6
#> 9        1     1    9 2019-10-20 20:16:00      NA           6
#> 10       1     1   10 2019-10-20 21:22:00       5          NA
#> 11       1     2   11 2019-10-21 08:42:00       1          NA
#> 12       1     2   12 2019-10-21 09:33:00      NA           1
#> 13       1     2   13 2019-10-21 11:38:00       6          NA
#> 14       1     2   14 2019-10-21 13:09:00       6           6
#> 15       1     2   15 2019-10-21 14:26:00       6           6
#> 16       1     2   16 2019-10-21 15:55:00      NA           6
#> 17       1     2   17 2019-10-21 17:18:00       6          NA
#> 18       1     2   18 2019-10-21 18:28:00       6           6
#> 19       1     2   19 2019-10-21 20:18:00       6           6
#> 20       1     2   20 2019-10-21 22:08:00       4           6
#> 21       2     1    1 2019-10-23 08:33:00       2          NA
#> 22       2     1    2 2019-10-23 09:18:00       7           2
#> 23       2     1    3 2019-10-23 11:36:00       7           7
#> 24       2     1    4 2019-10-23 12:57:00      NA           7
#> 25       2     1    5 2019-10-23 14:13:00      NA          NA
#> 26       2     1    6 2019-10-23 15:55:00       7          NA
#> 27       2     1    7 2019-10-23 16:52:00       7           7
#> 28       2     1    8 2019-10-23 19:23:00       1           7
#> 29       2     1    9 2019-10-23 20:13:00       7           1
#> 30       2     1   10 2019-10-23 21:40:00       6           7
#> 31       2     2   11 2019-10-24 08:58:00      NA          NA
#> 32       2     2   12 2019-10-24 09:55:00       7          NA
#> 33       2     2   13 2019-10-24 11:41:00       6           7
#> 34       2     2   14 2019-10-24 13:09:00      NA           6
#> 35       2     2   15 2019-10-24 15:06:00      NA          NA
#> 36       2     2   16 2019-10-24 16:01:00      NA          NA
#> 37       2     2   17 2019-10-24 17:36:00       7          NA
#> 38       2     2   18 2019-10-24 19:38:00       4           7
#> 39       2     2   19 2019-10-24 21:06:00       7           4
#> 40       2     2   20 2019-10-24 22:16:00       7           7

# lag the variable by two observations
dat$relaxed_lag <- lagvar(relaxed, id=subject, obs=beep, day=dayno, data=dat, lag=2)
dat
#>    subject dayno beep            beeptime relaxed relaxed_lag
#> 1        1     1    1 2019-10-20 08:03:00       2          NA
#> 2        1     1    2 2019-10-20 10:00:00       6          NA
#> 3        1     1    3 2019-10-20 11:18:00       6           2
#> 4        1     1    4 2019-10-20 12:34:00       6           6
#> 5        1     1    5 2019-10-20 14:16:00       5           6
#> 6        1     1    6 2019-10-20 16:15:00       6           6
#> 7        1     1    7 2019-10-20 16:47:00       6           5
#> 8        1     1    8 2019-10-20 19:01:00       6           6
#> 9        1     1    9 2019-10-20 20:16:00      NA           6
#> 10       1     1   10 2019-10-20 21:22:00       5           6
#> 11       1     2   11 2019-10-21 08:42:00       1          NA
#> 12       1     2   12 2019-10-21 09:33:00      NA          NA
#> 13       1     2   13 2019-10-21 11:38:00       6           1
#> 14       1     2   14 2019-10-21 13:09:00       6          NA
#> 15       1     2   15 2019-10-21 14:26:00       6           6
#> 16       1     2   16 2019-10-21 15:55:00      NA           6
#> 17       1     2   17 2019-10-21 17:18:00       6           6
#> 18       1     2   18 2019-10-21 18:28:00       6          NA
#> 19       1     2   19 2019-10-21 20:18:00       6           6
#> 20       1     2   20 2019-10-21 22:08:00       4           6
#> 21       2     1    1 2019-10-23 08:33:00       2          NA
#> 22       2     1    2 2019-10-23 09:18:00       7          NA
#> 23       2     1    3 2019-10-23 11:36:00       7           2
#> 24       2     1    4 2019-10-23 12:57:00      NA           7
#> 25       2     1    5 2019-10-23 14:13:00      NA           7
#> 26       2     1    6 2019-10-23 15:55:00       7          NA
#> 27       2     1    7 2019-10-23 16:52:00       7          NA
#> 28       2     1    8 2019-10-23 19:23:00       1           7
#> 29       2     1    9 2019-10-23 20:13:00       7           7
#> 30       2     1   10 2019-10-23 21:40:00       6           1
#> 31       2     2   11 2019-10-24 08:58:00      NA          NA
#> 32       2     2   12 2019-10-24 09:55:00       7          NA
#> 33       2     2   13 2019-10-24 11:41:00       6          NA
#> 34       2     2   14 2019-10-24 13:09:00      NA           7
#> 35       2     2   15 2019-10-24 15:06:00      NA           6
#> 36       2     2   16 2019-10-24 16:01:00      NA          NA
#> 37       2     2   17 2019-10-24 17:36:00       7          NA
#> 38       2     2   18 2019-10-24 19:38:00       4          NA
#> 39       2     2   19 2019-10-24 21:06:00       7           7
#> 40       2     2   20 2019-10-24 22:16:00       7           4

# lag the variable by up to 5 observations (taking whatever lag is smallest)
# note: this creates two variables (xl and lag), which we can add back to the dataset
tmp <- lagvar(relaxed, id=subject, obs=beep, day=dayno, data=dat, lag=1:5)
dat$relaxed_lag <- tmp$xl
dat$lag <- tmp$lag
dat
#>    subject dayno beep            beeptime relaxed relaxed_lag lag
#> 1        1     1    1 2019-10-20 08:03:00       2          NA  NA
#> 2        1     1    2 2019-10-20 10:00:00       6           2   1
#> 3        1     1    3 2019-10-20 11:18:00       6           6   1
#> 4        1     1    4 2019-10-20 12:34:00       6           6   1
#> 5        1     1    5 2019-10-20 14:16:00       5           6   1
#> 6        1     1    6 2019-10-20 16:15:00       6           5   1
#> 7        1     1    7 2019-10-20 16:47:00       6           6   1
#> 8        1     1    8 2019-10-20 19:01:00       6           6   1
#> 9        1     1    9 2019-10-20 20:16:00      NA           6   1
#> 10       1     1   10 2019-10-20 21:22:00       5           6   2
#> 11       1     2   11 2019-10-21 08:42:00       1          NA  NA
#> 12       1     2   12 2019-10-21 09:33:00      NA           1   1
#> 13       1     2   13 2019-10-21 11:38:00       6           1   2
#> 14       1     2   14 2019-10-21 13:09:00       6           6   1
#> 15       1     2   15 2019-10-21 14:26:00       6           6   1
#> 16       1     2   16 2019-10-21 15:55:00      NA           6   1
#> 17       1     2   17 2019-10-21 17:18:00       6           6   2
#> 18       1     2   18 2019-10-21 18:28:00       6           6   1
#> 19       1     2   19 2019-10-21 20:18:00       6           6   1
#> 20       1     2   20 2019-10-21 22:08:00       4           6   1
#> 21       2     1    1 2019-10-23 08:33:00       2          NA  NA
#> 22       2     1    2 2019-10-23 09:18:00       7           2   1
#> 23       2     1    3 2019-10-23 11:36:00       7           7   1
#> 24       2     1    4 2019-10-23 12:57:00      NA           7   1
#> 25       2     1    5 2019-10-23 14:13:00      NA           7   2
#> 26       2     1    6 2019-10-23 15:55:00       7           7   3
#> 27       2     1    7 2019-10-23 16:52:00       7           7   1
#> 28       2     1    8 2019-10-23 19:23:00       1           7   1
#> 29       2     1    9 2019-10-23 20:13:00       7           1   1
#> 30       2     1   10 2019-10-23 21:40:00       6           7   1
#> 31       2     2   11 2019-10-24 08:58:00      NA          NA  NA
#> 32       2     2   12 2019-10-24 09:55:00       7          NA  NA
#> 33       2     2   13 2019-10-24 11:41:00       6           7   1
#> 34       2     2   14 2019-10-24 13:09:00      NA           6   1
#> 35       2     2   15 2019-10-24 15:06:00      NA           6   2
#> 36       2     2   16 2019-10-24 16:01:00      NA           6   3
#> 37       2     2   17 2019-10-24 17:36:00       7           6   4
#> 38       2     2   18 2019-10-24 19:38:00       4           7   1
#> 39       2     2   19 2019-10-24 21:06:00       7           4   1
#> 40       2     2   20 2019-10-24 22:16:00       7           7   1

# remove those new variables
dat$relaxed_lag <- NULL
dat$lag <- NULL
dat
#>    subject dayno beep            beeptime relaxed
#> 1        1     1    1 2019-10-20 08:03:00       2
#> 2        1     1    2 2019-10-20 10:00:00       6
#> 3        1     1    3 2019-10-20 11:18:00       6
#> 4        1     1    4 2019-10-20 12:34:00       6
#> 5        1     1    5 2019-10-20 14:16:00       5
#> 6        1     1    6 2019-10-20 16:15:00       6
#> 7        1     1    7 2019-10-20 16:47:00       6
#> 8        1     1    8 2019-10-20 19:01:00       6
#> 9        1     1    9 2019-10-20 20:16:00      NA
#> 10       1     1   10 2019-10-20 21:22:00       5
#> 11       1     2   11 2019-10-21 08:42:00       1
#> 12       1     2   12 2019-10-21 09:33:00      NA
#> 13       1     2   13 2019-10-21 11:38:00       6
#> 14       1     2   14 2019-10-21 13:09:00       6
#> 15       1     2   15 2019-10-21 14:26:00       6
#> 16       1     2   16 2019-10-21 15:55:00      NA
#> 17       1     2   17 2019-10-21 17:18:00       6
#> 18       1     2   18 2019-10-21 18:28:00       6
#> 19       1     2   19 2019-10-21 20:18:00       6
#> 20       1     2   20 2019-10-21 22:08:00       4
#> 21       2     1    1 2019-10-23 08:33:00       2
#> 22       2     1    2 2019-10-23 09:18:00       7
#> 23       2     1    3 2019-10-23 11:36:00       7
#> 24       2     1    4 2019-10-23 12:57:00      NA
#> 25       2     1    5 2019-10-23 14:13:00      NA
#> 26       2     1    6 2019-10-23 15:55:00       7
#> 27       2     1    7 2019-10-23 16:52:00       7
#> 28       2     1    8 2019-10-23 19:23:00       1
#> 29       2     1    9 2019-10-23 20:13:00       7
#> 30       2     1   10 2019-10-23 21:40:00       6
#> 31       2     2   11 2019-10-24 08:58:00      NA
#> 32       2     2   12 2019-10-24 09:55:00       7
#> 33       2     2   13 2019-10-24 11:41:00       6
#> 34       2     2   14 2019-10-24 13:09:00      NA
#> 35       2     2   15 2019-10-24 15:06:00      NA
#> 36       2     2   16 2019-10-24 16:01:00      NA
#> 37       2     2   17 2019-10-24 17:36:00       7
#> 38       2     2   18 2019-10-24 19:38:00       4
#> 39       2     2   19 2019-10-24 21:06:00       7
#> 40       2     2   20 2019-10-24 22:16:00       7

# lag the relaxed variable and also get the time difference
tmp <- lagvar(relaxed, id=subject, obs=beep, day=dayno, time=beeptime, data=dat)
dat$relaxed_lag <- tmp$xl
dat$timelag <- tmp$timelag
dat
#>    subject dayno beep            beeptime relaxed relaxed_lag   timelag
#> 1        1     1    1 2019-10-20 08:03:00       2          NA   NA secs
#> 2        1     1    2 2019-10-20 10:00:00       6           2 7020 secs
#> 3        1     1    3 2019-10-20 11:18:00       6           6 4680 secs
#> 4        1     1    4 2019-10-20 12:34:00       6           6 4560 secs
#> 5        1     1    5 2019-10-20 14:16:00       5           6 6120 secs
#> 6        1     1    6 2019-10-20 16:15:00       6           5 7140 secs
#> 7        1     1    7 2019-10-20 16:47:00       6           6 1920 secs
#> 8        1     1    8 2019-10-20 19:01:00       6           6 8040 secs
#> 9        1     1    9 2019-10-20 20:16:00      NA           6 4500 secs
#> 10       1     1   10 2019-10-20 21:22:00       5          NA   NA secs
#> 11       1     2   11 2019-10-21 08:42:00       1          NA   NA secs
#> 12       1     2   12 2019-10-21 09:33:00      NA           1 3060 secs
#> 13       1     2   13 2019-10-21 11:38:00       6          NA   NA secs
#> 14       1     2   14 2019-10-21 13:09:00       6           6 5460 secs
#> 15       1     2   15 2019-10-21 14:26:00       6           6 4620 secs
#> 16       1     2   16 2019-10-21 15:55:00      NA           6 5340 secs
#> 17       1     2   17 2019-10-21 17:18:00       6          NA   NA secs
#> 18       1     2   18 2019-10-21 18:28:00       6           6 4200 secs
#> 19       1     2   19 2019-10-21 20:18:00       6           6 6600 secs
#> 20       1     2   20 2019-10-21 22:08:00       4           6 6600 secs
#> 21       2     1    1 2019-10-23 08:33:00       2          NA   NA secs
#> 22       2     1    2 2019-10-23 09:18:00       7           2 2700 secs
#> 23       2     1    3 2019-10-23 11:36:00       7           7 8280 secs
#> 24       2     1    4 2019-10-23 12:57:00      NA           7 4860 secs
#> 25       2     1    5 2019-10-23 14:13:00      NA          NA   NA secs
#> 26       2     1    6 2019-10-23 15:55:00       7          NA   NA secs
#> 27       2     1    7 2019-10-23 16:52:00       7           7 3420 secs
#> 28       2     1    8 2019-10-23 19:23:00       1           7 9060 secs
#> 29       2     1    9 2019-10-23 20:13:00       7           1 3000 secs
#> 30       2     1   10 2019-10-23 21:40:00       6           7 5220 secs
#> 31       2     2   11 2019-10-24 08:58:00      NA          NA   NA secs
#> 32       2     2   12 2019-10-24 09:55:00       7          NA   NA secs
#> 33       2     2   13 2019-10-24 11:41:00       6           7 6360 secs
#> 34       2     2   14 2019-10-24 13:09:00      NA           6 5280 secs
#> 35       2     2   15 2019-10-24 15:06:00      NA          NA   NA secs
#> 36       2     2   16 2019-10-24 16:01:00      NA          NA   NA secs
#> 37       2     2   17 2019-10-24 17:36:00       7          NA   NA secs
#> 38       2     2   18 2019-10-24 19:38:00       4           7 7320 secs
#> 39       2     2   19 2019-10-24 21:06:00       7           4 5280 secs
#> 40       2     2   20 2019-10-24 22:16:00       7           7 4200 secs

# timelag in minutes
dat$timelag <- as.numeric(tmp$timelag, units="mins")
dat
#>    subject dayno beep            beeptime relaxed relaxed_lag timelag
#> 1        1     1    1 2019-10-20 08:03:00       2          NA      NA
#> 2        1     1    2 2019-10-20 10:00:00       6           2     117
#> 3        1     1    3 2019-10-20 11:18:00       6           6      78
#> 4        1     1    4 2019-10-20 12:34:00       6           6      76
#> 5        1     1    5 2019-10-20 14:16:00       5           6     102
#> 6        1     1    6 2019-10-20 16:15:00       6           5     119
#> 7        1     1    7 2019-10-20 16:47:00       6           6      32
#> 8        1     1    8 2019-10-20 19:01:00       6           6     134
#> 9        1     1    9 2019-10-20 20:16:00      NA           6      75
#> 10       1     1   10 2019-10-20 21:22:00       5          NA      NA
#> 11       1     2   11 2019-10-21 08:42:00       1          NA      NA
#> 12       1     2   12 2019-10-21 09:33:00      NA           1      51
#> 13       1     2   13 2019-10-21 11:38:00       6          NA      NA
#> 14       1     2   14 2019-10-21 13:09:00       6           6      91
#> 15       1     2   15 2019-10-21 14:26:00       6           6      77
#> 16       1     2   16 2019-10-21 15:55:00      NA           6      89
#> 17       1     2   17 2019-10-21 17:18:00       6          NA      NA
#> 18       1     2   18 2019-10-21 18:28:00       6           6      70
#> 19       1     2   19 2019-10-21 20:18:00       6           6     110
#> 20       1     2   20 2019-10-21 22:08:00       4           6     110
#> 21       2     1    1 2019-10-23 08:33:00       2          NA      NA
#> 22       2     1    2 2019-10-23 09:18:00       7           2      45
#> 23       2     1    3 2019-10-23 11:36:00       7           7     138
#> 24       2     1    4 2019-10-23 12:57:00      NA           7      81
#> 25       2     1    5 2019-10-23 14:13:00      NA          NA      NA
#> 26       2     1    6 2019-10-23 15:55:00       7          NA      NA
#> 27       2     1    7 2019-10-23 16:52:00       7           7      57
#> 28       2     1    8 2019-10-23 19:23:00       1           7     151
#> 29       2     1    9 2019-10-23 20:13:00       7           1      50
#> 30       2     1   10 2019-10-23 21:40:00       6           7      87
#> 31       2     2   11 2019-10-24 08:58:00      NA          NA      NA
#> 32       2     2   12 2019-10-24 09:55:00       7          NA      NA
#> 33       2     2   13 2019-10-24 11:41:00       6           7     106
#> 34       2     2   14 2019-10-24 13:09:00      NA           6      88
#> 35       2     2   15 2019-10-24 15:06:00      NA          NA      NA
#> 36       2     2   16 2019-10-24 16:01:00      NA          NA      NA
#> 37       2     2   17 2019-10-24 17:36:00       7          NA      NA
#> 38       2     2   18 2019-10-24 19:38:00       4           7     122
#> 39       2     2   19 2019-10-24 21:06:00       7           4      88
#> 40       2     2   20 2019-10-24 22:16:00       7           7      70

# remove those new variables
dat$relaxed_lag <- NULL
dat$timelag <- NULL
dat
#>    subject dayno beep            beeptime relaxed
#> 1        1     1    1 2019-10-20 08:03:00       2
#> 2        1     1    2 2019-10-20 10:00:00       6
#> 3        1     1    3 2019-10-20 11:18:00       6
#> 4        1     1    4 2019-10-20 12:34:00       6
#> 5        1     1    5 2019-10-20 14:16:00       5
#> 6        1     1    6 2019-10-20 16:15:00       6
#> 7        1     1    7 2019-10-20 16:47:00       6
#> 8        1     1    8 2019-10-20 19:01:00       6
#> 9        1     1    9 2019-10-20 20:16:00      NA
#> 10       1     1   10 2019-10-20 21:22:00       5
#> 11       1     2   11 2019-10-21 08:42:00       1
#> 12       1     2   12 2019-10-21 09:33:00      NA
#> 13       1     2   13 2019-10-21 11:38:00       6
#> 14       1     2   14 2019-10-21 13:09:00       6
#> 15       1     2   15 2019-10-21 14:26:00       6
#> 16       1     2   16 2019-10-21 15:55:00      NA
#> 17       1     2   17 2019-10-21 17:18:00       6
#> 18       1     2   18 2019-10-21 18:28:00       6
#> 19       1     2   19 2019-10-21 20:18:00       6
#> 20       1     2   20 2019-10-21 22:08:00       4
#> 21       2     1    1 2019-10-23 08:33:00       2
#> 22       2     1    2 2019-10-23 09:18:00       7
#> 23       2     1    3 2019-10-23 11:36:00       7
#> 24       2     1    4 2019-10-23 12:57:00      NA
#> 25       2     1    5 2019-10-23 14:13:00      NA
#> 26       2     1    6 2019-10-23 15:55:00       7
#> 27       2     1    7 2019-10-23 16:52:00       7
#> 28       2     1    8 2019-10-23 19:23:00       1
#> 29       2     1    9 2019-10-23 20:13:00       7
#> 30       2     1   10 2019-10-23 21:40:00       6
#> 31       2     2   11 2019-10-24 08:58:00      NA
#> 32       2     2   12 2019-10-24 09:55:00       7
#> 33       2     2   13 2019-10-24 11:41:00       6
#> 34       2     2   14 2019-10-24 13:09:00      NA
#> 35       2     2   15 2019-10-24 15:06:00      NA
#> 36       2     2   16 2019-10-24 16:01:00      NA
#> 37       2     2   17 2019-10-24 17:36:00       7
#> 38       2     2   18 2019-10-24 19:38:00       4
#> 39       2     2   19 2019-10-24 21:06:00       7
#> 40       2     2   20 2019-10-24 22:16:00       7

# suppose the 'dayno' variable is not available
dat$dayno <- NULL
dat
#>    subject beep            beeptime relaxed
#> 1        1    1 2019-10-20 08:03:00       2
#> 2        1    2 2019-10-20 10:00:00       6
#> 3        1    3 2019-10-20 11:18:00       6
#> 4        1    4 2019-10-20 12:34:00       6
#> 5        1    5 2019-10-20 14:16:00       5
#> 6        1    6 2019-10-20 16:15:00       6
#> 7        1    7 2019-10-20 16:47:00       6
#> 8        1    8 2019-10-20 19:01:00       6
#> 9        1    9 2019-10-20 20:16:00      NA
#> 10       1   10 2019-10-20 21:22:00       5
#> 11       1   11 2019-10-21 08:42:00       1
#> 12       1   12 2019-10-21 09:33:00      NA
#> 13       1   13 2019-10-21 11:38:00       6
#> 14       1   14 2019-10-21 13:09:00       6
#> 15       1   15 2019-10-21 14:26:00       6
#> 16       1   16 2019-10-21 15:55:00      NA
#> 17       1   17 2019-10-21 17:18:00       6
#> 18       1   18 2019-10-21 18:28:00       6
#> 19       1   19 2019-10-21 20:18:00       6
#> 20       1   20 2019-10-21 22:08:00       4
#> 21       2    1 2019-10-23 08:33:00       2
#> 22       2    2 2019-10-23 09:18:00       7
#> 23       2    3 2019-10-23 11:36:00       7
#> 24       2    4 2019-10-23 12:57:00      NA
#> 25       2    5 2019-10-23 14:13:00      NA
#> 26       2    6 2019-10-23 15:55:00       7
#> 27       2    7 2019-10-23 16:52:00       7
#> 28       2    8 2019-10-23 19:23:00       1
#> 29       2    9 2019-10-23 20:13:00       7
#> 30       2   10 2019-10-23 21:40:00       6
#> 31       2   11 2019-10-24 08:58:00      NA
#> 32       2   12 2019-10-24 09:55:00       7
#> 33       2   13 2019-10-24 11:41:00       6
#> 34       2   14 2019-10-24 13:09:00      NA
#> 35       2   15 2019-10-24 15:06:00      NA
#> 36       2   16 2019-10-24 16:01:00      NA
#> 37       2   17 2019-10-24 17:36:00       7
#> 38       2   18 2019-10-24 19:38:00       4
#> 39       2   19 2019-10-24 21:06:00       7
#> 40       2   20 2019-10-24 22:16:00       7

# we can recreate this based on the 'beeptime' variable
dat$dayno <- unsplit(
   lapply(split(dat$beeptime, dat$subject), function(x) {
      z <- format(x, format="%Y-%m-%d")
      as.numeric(difftime(z, z[1], units="days")) + 1
   }), dat$subject)
dat
#>    subject beep            beeptime relaxed dayno
#> 1        1    1 2019-10-20 08:03:00       2     1
#> 2        1    2 2019-10-20 10:00:00       6     1
#> 3        1    3 2019-10-20 11:18:00       6     1
#> 4        1    4 2019-10-20 12:34:00       6     1
#> 5        1    5 2019-10-20 14:16:00       5     1
#> 6        1    6 2019-10-20 16:15:00       6     1
#> 7        1    7 2019-10-20 16:47:00       6     1
#> 8        1    8 2019-10-20 19:01:00       6     1
#> 9        1    9 2019-10-20 20:16:00      NA     1
#> 10       1   10 2019-10-20 21:22:00       5     1
#> 11       1   11 2019-10-21 08:42:00       1     2
#> 12       1   12 2019-10-21 09:33:00      NA     2
#> 13       1   13 2019-10-21 11:38:00       6     2
#> 14       1   14 2019-10-21 13:09:00       6     2
#> 15       1   15 2019-10-21 14:26:00       6     2
#> 16       1   16 2019-10-21 15:55:00      NA     2
#> 17       1   17 2019-10-21 17:18:00       6     2
#> 18       1   18 2019-10-21 18:28:00       6     2
#> 19       1   19 2019-10-21 20:18:00       6     2
#> 20       1   20 2019-10-21 22:08:00       4     2
#> 21       2    1 2019-10-23 08:33:00       2     1
#> 22       2    2 2019-10-23 09:18:00       7     1
#> 23       2    3 2019-10-23 11:36:00       7     1
#> 24       2    4 2019-10-23 12:57:00      NA     1
#> 25       2    5 2019-10-23 14:13:00      NA     1
#> 26       2    6 2019-10-23 15:55:00       7     1
#> 27       2    7 2019-10-23 16:52:00       7     1
#> 28       2    8 2019-10-23 19:23:00       1     1
#> 29       2    9 2019-10-23 20:13:00       7     1
#> 30       2   10 2019-10-23 21:40:00       6     1
#> 31       2   11 2019-10-24 08:58:00      NA     2
#> 32       2   12 2019-10-24 09:55:00       7     2
#> 33       2   13 2019-10-24 11:41:00       6     2
#> 34       2   14 2019-10-24 13:09:00      NA     2
#> 35       2   15 2019-10-24 15:06:00      NA     2
#> 36       2   16 2019-10-24 16:01:00      NA     2
#> 37       2   17 2019-10-24 17:36:00       7     2
#> 38       2   18 2019-10-24 19:38:00       4     2
#> 39       2   19 2019-10-24 21:06:00       7     2
#> 40       2   20 2019-10-24 22:16:00       7     2

# now suppose the dataset does not include beeps that were not responded to
dat <- dat[!is.na(dat$relaxed),]
dat
#>    subject beep            beeptime relaxed dayno
#> 1        1    1 2019-10-20 08:03:00       2     1
#> 2        1    2 2019-10-20 10:00:00       6     1
#> 3        1    3 2019-10-20 11:18:00       6     1
#> 4        1    4 2019-10-20 12:34:00       6     1
#> 5        1    5 2019-10-20 14:16:00       5     1
#> 6        1    6 2019-10-20 16:15:00       6     1
#> 7        1    7 2019-10-20 16:47:00       6     1
#> 8        1    8 2019-10-20 19:01:00       6     1
#> 10       1   10 2019-10-20 21:22:00       5     1
#> 11       1   11 2019-10-21 08:42:00       1     2
#> 13       1   13 2019-10-21 11:38:00       6     2
#> 14       1   14 2019-10-21 13:09:00       6     2
#> 15       1   15 2019-10-21 14:26:00       6     2
#> 17       1   17 2019-10-21 17:18:00       6     2
#> 18       1   18 2019-10-21 18:28:00       6     2
#> 19       1   19 2019-10-21 20:18:00       6     2
#> 20       1   20 2019-10-21 22:08:00       4     2
#> 21       2    1 2019-10-23 08:33:00       2     1
#> 22       2    2 2019-10-23 09:18:00       7     1
#> 23       2    3 2019-10-23 11:36:00       7     1
#> 26       2    6 2019-10-23 15:55:00       7     1
#> 27       2    7 2019-10-23 16:52:00       7     1
#> 28       2    8 2019-10-23 19:23:00       1     1
#> 29       2    9 2019-10-23 20:13:00       7     1
#> 30       2   10 2019-10-23 21:40:00       6     1
#> 32       2   12 2019-10-24 09:55:00       7     2
#> 33       2   13 2019-10-24 11:41:00       6     2
#> 37       2   17 2019-10-24 17:36:00       7     2
#> 38       2   18 2019-10-24 19:38:00       4     2
#> 39       2   19 2019-10-24 21:06:00       7     2
#> 40       2   20 2019-10-24 22:16:00       7     2

# in this case, specifying the 'obs' variable (i.e., 'beep') is crucial
# note: the lagged value for beep 10 is missing, since beep 9 is missing
dat$relaxed_lag <- lagvar(relaxed, id=subject, obs=beep, day=dayno, data=dat)
dat
#>    subject beep            beeptime relaxed dayno relaxed_lag
#> 1        1    1 2019-10-20 08:03:00       2     1          NA
#> 2        1    2 2019-10-20 10:00:00       6     1           2
#> 3        1    3 2019-10-20 11:18:00       6     1           6
#> 4        1    4 2019-10-20 12:34:00       6     1           6
#> 5        1    5 2019-10-20 14:16:00       5     1           6
#> 6        1    6 2019-10-20 16:15:00       6     1           5
#> 7        1    7 2019-10-20 16:47:00       6     1           6
#> 8        1    8 2019-10-20 19:01:00       6     1           6
#> 10       1   10 2019-10-20 21:22:00       5     1          NA
#> 11       1   11 2019-10-21 08:42:00       1     2          NA
#> 13       1   13 2019-10-21 11:38:00       6     2          NA
#> 14       1   14 2019-10-21 13:09:00       6     2           6
#> 15       1   15 2019-10-21 14:26:00       6     2           6
#> 17       1   17 2019-10-21 17:18:00       6     2          NA
#> 18       1   18 2019-10-21 18:28:00       6     2           6
#> 19       1   19 2019-10-21 20:18:00       6     2           6
#> 20       1   20 2019-10-21 22:08:00       4     2           6
#> 21       2    1 2019-10-23 08:33:00       2     1          NA
#> 22       2    2 2019-10-23 09:18:00       7     1           2
#> 23       2    3 2019-10-23 11:36:00       7     1           7
#> 26       2    6 2019-10-23 15:55:00       7     1          NA
#> 27       2    7 2019-10-23 16:52:00       7     1           7
#> 28       2    8 2019-10-23 19:23:00       1     1           7
#> 29       2    9 2019-10-23 20:13:00       7     1           1
#> 30       2   10 2019-10-23 21:40:00       6     1           7
#> 32       2   12 2019-10-24 09:55:00       7     2          NA
#> 33       2   13 2019-10-24 11:41:00       6     2           7
#> 37       2   17 2019-10-24 17:36:00       7     2          NA
#> 38       2   18 2019-10-24 19:38:00       4     2           7
#> 39       2   19 2019-10-24 21:06:00       7     2           4
#> 40       2   20 2019-10-24 22:16:00       7     2           7