R - Indicate per group if a certain column is uniform or contains different factor values

Viewed 66

I have a df with over 5000 group IDs. Each group contains one or multiple observations (measurements). A second column indicates the status of whether a measurement was completed or not completed. In most cases, all measurements within one group should contain the same status, but that is not always the case (e.g. group B in the example code). In some cases, the status might be missing and will be filtered.

tibble(group_id=factor(c("A", "A", "A","B","B","B","C")), 
       status=factor(c("complete","complete", NA, "complete", "not complete", "complete", "complete")))


group_id status      
<fct>    <fct>       
1 A        complete    
2 A        complete    
3 A        NA    
4 B        complete    
5 B        not complete
6 B        complete    
7 C        complete

What I would like to do is to 1.) create an indicator column to indicate which groups differ in status within their group (not taking NA into account) en 2.) if the status differs within a group, group the rows based on the factors.

group_id   status        uniform_status   status_group
1 A        complete        TRUE             NA
2 A        complete        TRUE             NA
3 A        NA              NA               NA
4 B        complete        FALSE            1
5 B        not complete    FALSE            2
6 B        complete        FALSE            1
7 C        complete        TRUE             NA

I think the second step can be easily done with some case_when mutation, but I'm a bit at loss at the first step as this requires conditions that are partially based on multiple rows.

1 Answers

Try with dplyr functions group_by and mutate:

library(dplyr)
df %>% group_by(group_id) %>%
  mutate(uniform_status=all(status != 'not complete')) %>%
  mutate(uniform_status=ifelse(is.na(uniform_status) & (status == 'complete'), T, uniform_status), status_group=ifelse(uniform_status == F, (status == 'not complete') + 1, NA))

Output:

# A tibble: 7 x 4
# Groups:   group_id [3]
  group_id status       uniform_status status_group
  <fct>    <fct>        <lgl>                 <dbl>
1 A        complete     TRUE                     NA
2 A        complete     TRUE                     NA
3 A        <NA>         NA                       NA
4 B        complete     FALSE                     1
5 B        not complete FALSE                     2
6 B        complete     FALSE                     1
7 C        complete     TRUE                     NA
Related