R — Укажите для каждой группы, является ли определенный столбец однородным или содержит различные значения факторов

#r #dplyr #grouping

Вопрос:

У меня есть df с более чем 5000 идентификаторами групп. Каждая группа содержит одно или несколько наблюдений (измерений). Во втором столбце указывается статус того, было ли измерение завершено или не завершено. В большинстве случаев все измерения в пределах одной группы должны иметь одинаковый статус, но это не всегда так (например, группа B в примере кода). В некоторых случаях статус может отсутствовать и будет отфильтрован.

 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
 

Что я хотел бы сделать, так это 1.) создать столбец индикатора, чтобы указать, какие группы отличаются статусом внутри своей группы (без учета NA). 2.) если статус отличается внутри группы, сгруппируйте строки на основе факторов.

 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
 

Я думаю, что второй шаг можно легко выполнить с некоторой мутацией case_when, но я немного растерян на первом шаге, так как для этого требуются условия, частично основанные на нескольких строках.

Ответ №1:

Попробуйте с dplyr функциями group_by и mutate :

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

Выход:

 # 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