I want to do a conditional slice on a grouped data set in R.
df <- data.frame(grp = c(1, 1, 2, 2, 3, 3),
vehicle = c("car", "boat", "bike", "car", "plane", "bike"))
#> grp vehicle
#> 1 1 car
#> 2 1 boat
#> 3 2 bike
#> 4 2 car
#> 5 3 plane
#> 6 3 bike
I would like to group by grp
and only keep groups where the first row is equal to car
. This would be the solution.
#> grp vehicle
#> 1 1 car
#> 2 1 boat
How do I do this? I think it could be a better version of this.
library(dplyr)
df %>% group_by(grp) %>% filter(any(slice_head(vehicle == "car")))
#, Error in `filter()`:
#, ! Problem while computing `..1 =
...
CodePudding user response:
It could be done without a grouping as well i.e. with duplicated
to find the first occurrence of 'grp' and check if the 'vehicle' value is "car" and use that to create a logical with 'grp'
library(dplyr)
df %>%
filter(grp %in% grp[!duplicated(grp) & vehicle == "car"])
grp vehicle
1 1 car
2 1 boat
CodePudding user response:
data.table
library(data.table)
DT <- as.data.table(df) # setDT is more canonical
DT[, .SD[first(vehicle) == "car",], by = .(grp)]
# grp vehicle
# <num> <char>
# 1: 1 car
# 2: 1 boat
CodePudding user response:
Another data.table solution:
library(data.table)
setDT(df)[, if(first(vehicle)=="car") .SD, by=grp]
grp vehicle
<num> <char>
1: 1 car
2: 1 boat