I would like to use a piped workflow to apply dplyr::case_when over a dataset of 10^4s of rows regularly, and would like to avoid rowwise as it is v slow.
I would like to match a large number of criteria to a given values, e.g. any(x = c(1:999, 3000:200000, 250000:250100), where length(x) is 1, and apply it to each row in a data.frame.
Something like this function but with many more criteria:
is_good_car <- function(x){
any(
x == c(
"Mazda RX4",
"Datsun 710",
"Valiant"
)
)
}
I could apply it like this:
library(dplyr)
mtcars %>%
mutate(
car = rownames(.)
) %>%
as_tibble %>%
mutate(
good_cars = case_when(
is_good_car(car) ~ "good",
TRUE ~ "rubbish"
)
) %>%
select(car, good_cars)
#> Warning in x == c("Mazda RX4", "Datsun 710", "Valiant"): longer object length is
#> not a multiple of shorter object length
#> # A tibble: 32 x 2
#> car good_cars
#> <chr> <chr>
#> 1 Mazda RX4 good
#> 2 Mazda RX4 Wag good
#> 3 Datsun 710 good
#> 4 Hornet 4 Drive good
#> 5 Hornet Sportabout good
#> 6 Valiant good
#> 7 Duster 360 good
#> 8 Merc 240D good
#> 9 Merc 230 good
#> 10 Merc 280 good
#> # ... with 22 more rows
But this doesn't work because it just returns a single TRUE from is_good_car and returns this to every row.
I can use rowwise to get the right answer but it's v slow for my purpose:
mtcars %>%
mutate(
car = rownames(.)
) %>%
as_tibble %>%
rowwise %>%
mutate(
good_cars = case_when(
is_good_car(car) ~ "good",
TRUE ~ "rubbish"
)
) %>%
select(car, good_cars)
#> # A tibble: 32 x 2
#> # Rowwise:
#> car good_cars
#> <chr> <chr>
#> 1 Mazda RX4 good
#> 2 Mazda RX4 Wag rubbish
#> 3 Datsun 710 good
#> 4 Hornet 4 Drive rubbish
#> 5 Hornet Sportabout rubbish
#> 6 Valiant good
#> 7 Duster 360 rubbish
#> 8 Merc 240D rubbish
#> 9 Merc 230 rubbish
#> 10 Merc 280 rubbish
#> # ... with 22 more rows
I could use sapply also but I want to work it into a piped workflow like above:
sapply(
X = rownames(mtcars),
FUN = is_good_car
)
#> Mazda RX4 Mazda RX4 Wag Datsun 710 Hornet 4 Drive
#> TRUE FALSE TRUE FALSE
#> Hornet Sportabout Valiant Duster 360 Merc 240D
#> FALSE TRUE FALSE FALSE
#> Merc 230 Merc 280 Merc 280C Merc 450SE
#> FALSE FALSE FALSE FALSE
#> Merc 450SL Merc 450SLC Cadillac Fleetwood Lincoln Continental
#> FALSE FALSE FALSE FALSE
#> Chrysler Imperial Fiat 128 Honda Civic Toyota Corolla
#> FALSE FALSE FALSE FALSE
#> Toyota Corona Dodge Challenger AMC Javelin Camaro Z28
#> FALSE FALSE FALSE FALSE
#> Pontiac Firebird Fiat X1-9 Porsche 914-2 Lotus Europa
#> FALSE FALSE FALSE FALSE
#> Ford Pantera L Ferrari Dino Maserati Bora Volvo 142E
#> FALSE FALSE FALSE FALSE
Are there any options to use function like is_good_car as desired, within case_when without using rowwise?
Created on 2021-09-22 by the reprex package (v2.0.1)