Using case_when() across grouped rows and selecting when item present - tidyverse/R solution

Viewed 136

I'm trying to use case_when() in tidyverse but specifically to output a particular category when any value in the grouped row of a column is present or not...

Dummy data (d):

ID  Tired
1A  No
1A  No
1A  Yes
1B  No
1B  No
IC  Yes
ID  No
ID  No

I want the output to classify whether each ID is tired or not. However, if the ID has said they are tired at least once, they count as tired and they are categorised as "Y". If they say no to being tired everytime, it is "N".

Desired output (output):

ID  Tired Category
1A  No     Y
1A  No
1A  Yes
1B  No     N
1B  No
IC  Yes    Y
ID  No     N
ID  No

I have some code, but it's falling down as I don't know how to code for the situation the category classification occurs once across a group, within a column:

output <- d %>% group_by(ID) %>% mutate(Category = case_when(
   Tired == "Yes" ~ Y,
    (TRUE) ~ N))

Any help would be gratefully received!

2 Answers

I think you're looking for any:

library(dplyr)

d %>%
  group_by(ID) %>% 
  mutate(Category = case_when(any(Tired ==  "Yes") ~ "Y",
                              TRUE ~ "N"))

Gives us:

  ID    Tired Category
  <chr> <chr> <chr>   
1 1A    No    Y       
2 1A    No    Y       
3 1A    Yes   Y       
4 1B    No    N       
5 1B    No    N       
6 IC    Yes   Y       
7 ID    No    N       
8 ID    No    N    

An option with arrange and substr

library(dpyr)
d %>% 
   arrange(ID, Tired == 'No') %>% 
   group_by(ID) %>% 
   mutate(Category =  substr(first(Tired), 1, 1)) %>%
   ungroup

-output

# A tibble: 8 x 3
#  ID    Tired Category
#  <chr> <chr> <chr>   
#1 1A    Yes   Y       
#2 1A    No    Y       
#3 1A    No    Y       
#4 1B    No    N       
#5 1B    No    N       
#6 IC    Yes   Y       
#7 ID    No    N       
#8 ID    No    N    

data

d <- structure(list(ID = c("1A", "1A", "1A", "1B", "1B", "IC", "ID", 
"ID"), Tired = c("No", "No", "Yes", "No", "No", "Yes", "No", 
"No")), class = "data.frame", row.names = c(NA, -8L))
Related