With the following dataframe, I would like to filter out rows based on two conditions. If the daily temperature is less than 41 I would like to extract the epi temperature, if it is >= 41 I would like to extract the meta temperature.
df <- data.frame(day = c(1, 1, 1, 2, 2, 2),
temperature = c(40, 39, 39, 45, 38, 30),
strata = c("epi", "meta", "hypo", "epi", "meta", "hypo"))
desired output:
day temperature strata
1 40 epi
2 38 meta
I cant quite wrap my head around how to code this using tidyverse.
CodePudding user response:
Here is a base R solution with ave
. Create a logical index on the temperature and keep the rows where the strata condition is met, conditional to the created index.
df <- data.frame(day = c(1, 1, 1, 2, 2, 2),
temperature = c(40, 39, 39, 45, 38, 30),
strata = c("epi", "meta", "hypo", "epi", "meta", "hypo"))
i <- as.logical(with(df, ave(temperature, day, FUN = \(x) all(x < 41))))
df[(i & df$strata == "epi") | (!i & df$strata == "meta"), ]
#> day temperature strata
#> 1 1 40 epi
#> 5 2 38 meta
Created on 2022-07-21 by the reprex package (v2.0.1)
And here is a dplyr
solution.
suppressPackageStartupMessages(library(dplyr))
df %>%
group_by(day) %>%
filter(
(any(temperature >= 41) & strata == "meta") |
(all(temperature < 41) & strata == "epi")
)
#> # A tibble: 2 × 3
#> # Groups: day [2]
#> day temperature strata
#> <dbl> <dbl> <chr>
#> 1 1 40 epi
#> 2 2 38 meta
Created on 2022-07-21 by the reprex package (v2.0.1)