How to remove all rows belonging to a particular group when only one row fulfills the condition in R?

StackOverflow https://stackoverflow.com/questions/23666817

  •  22-07-2023
  •  | 
  •  

Question

Following is my sample data set:

> dput(lanec)
structure(list(vehicle.id = c(2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L), frame.id = c(1L, 2L, 3L, 4L, 5L, 3L, 4L, 5L, 6L, 7L, 
8L, 9L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 6L, 7L, 8L, 9L, 10L, 11L, 
12L), lane.change = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 
2L, 1L), .Label = c(".", "yes"), class = "factor")), .Names = c("vehicle.id", 
"frame.id", "lane.change"), class = "data.frame", row.names = c(NA, 
-26L))

The first column is the IDs of vehicles entering on a particular segment of a freeway. They were observed until they left the segment so each vehicle has different number of time frames in which it was observed. The frame numbers are given in frame.id column. The third column tells whether the vehicle changed the lane and in which frame. In this sample data all except vehicle # 2 changed the lane. Vehicle # 5 changed the lane twice.

Required

I want to identify which vehicles changed the lane and remove them from data set. I tried using subset(lanec, lane.change!='yes') but it only remove those rows where the value of lane.change is yes. Using the sample data set, the desired output should be:

vehicle.id frame.id lane.change
1           2        1           .
2           2        2           .
3           2        3           .
4           2        4           .
5           2        5           .

How can I achieve this? It must be simple but I can't figure it out. Thanks in advance.

Was it helpful?

Solution

You can do:

subset(lanec, ave(lane.change != "yes", vehicle.id, FUN = all))

To help understand what ave returns, maybe you can break it into a couple steps:

lanec <- transform(lanec, stays.in.lane = ave(lane.change != "yes", vehicle.id, FUN = all))
subset(lanec, stays.in.lane)

You will see that ave returns a vector of TRUE/FALSE along lanec: whether the vehicle.id had all (hence the use of all) of its lane.change values not equal to 'yes'.

OTHER TIPS

 steady <- names( which(with(lanec, tapply(lane.change, vehicle.id, function(x) all(x==".")) ) ))
steady
[1] "2"

So pick the onew where all the items in lane.change are "."

lanec[ lanec$vehicle.id %in% steady, ]
#-------

  vehicle.id frame.id lane.change
1          2        1           .
2          2        2           .
3          2        3           .
4          2        4           .
5          2        5           .
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top