How to label any range of values around a specific row in R?

Viewed 533

This is a follow-up question to this one.

Data

x <- data.frame(file.ID = "Car1", 
                frames = 1:15, 
                lane.change = c("no", "no", "no", "yes", 
                                "no", "no", "no", "no", 
                                "no", "yes", "no", "no", "no", "no", "no"))

Problem

I want to label few rows above and few rows after the lane.change=="yes" row in each lane change for a given file.ID group. The answers to previous question work for consecutive rows but not for any number of rows. I tried providing the argument n in lead and lag functions but it does not give desired results.

Desired Output

Ideally, I want to be able to label any number of rows before and after lane.change=="yes".In my original data frame I want to label 800 rows before and after. But in the sample data frame x I am trying to label 2. So the desired output should be:

   file.ID frames lane.change range_LC
1     Car1      1          no        .
2     Car1      2          no      LC1
3     Car1      3          no      LC1
4     Car1      4         yes      LC1
5     Car1      5          no      LC1
6     Car1      6          no      LC1
7     Car1      7          no        .
8     Car1      8          no      LC2
9     Car1      9          no      LC2
10    Car1     10         yes      LC2
11    Car1     11          no      LC2
12    Car1     12          no      LC2
13    Car1     13          no        .
14    Car1     14          no        .
15    Car1     15          no        .

Please help me get the desired output. Since the original data has multiple file.IDs, I prefer a dplyr solution because I can later use group_by. Thanks.

EDIT

I want to generalize the code for multiple file.IDs. You can download the subset of original data frame that contains 2 file.IDs, here. I tried following (thanks to @G5W's solution):

library(tidyr)
by_file.ID <- c %>% 
  group_by(file.ID) %>% 
  nest()

library(purrr)
by_file.ID <- by_file.ID %>% 
  mutate(range_LC = map(data, ~ ".")) %>% 
  mutate(Changes = map(data, ~ tail(which(.$lane.change=="yes"),-1)))   

Please note that 1st lane change in each case is at a very small index number. So, I skip it by doing tail(which(...), -1). Also, note that in these data I want to use 800 rows before and after lane change row. So, the code for individual file.IDs should be something like this:

range_LC[t(outer(Changes, -800:800, '+'))] = rep(1:length(Changes), each=1601)

The line above is the main piece of code that I am not sure how to apply to the groups of file.IDs. I thought about using a for loop with do.call() but it is likely to be very slow due to a large number of lane changes and file.IDs.

Thanks for your time and effort in helping me.

3 Answers
Related