Узнайте, все ли столбцы в группе одинаковы в R

#r

#r

Вопрос:

У меня есть фрейм данных, df :

 df <- structure(list(ID = structure(c("ID961", "ID961", 
"ID961", "ID961", "ID726", 
"ID726", "ID726", "ID864", 
"ID864", "ID864"), label = "ID"), 
    TYPE = structure(c("blind", "blind", "blind", "blind", 
    "blind", "blind", "blind", "blind", "blind", "notblind"
    ), label = "blind or not"), AGE = structure(c(50, 
    50, 50, 50, 67, 67, 67, 35, 35, 35), label = "Age"), AGEU = structure(c("YEARS", 
    "YEARS", "YEARS", "YEARS", "YEARS", "YEARS", "YEARS", "YEARS", 
    "YEARS", "YEARS"), label = "Age Units"), AVISIT = structure(c("26", 
    "46", "46", "36", "66", 
    "64", "67", "37", "37", 
    "67"), label = "treat")), row.names = c(NA, 
-10L), class = c("tbl_df", "tbl", "data.frame"), label = "df")

> df
# A tibble: 10 x 5
   ID    TYPE    AGE AGEU  AVISIT
   <chr> <chr> <dbl> <chr> <chr> 
 1 ID961 blind    50 YEARS 26    
 2 ID961 blind    50 YEARS 46    
 3 ID961 blind    50 YEARS 46    
 4 ID961 blind    50 YEARS 36    
 5 ID726 blind    67 YEARS 66    
 6 ID726 blind    67 YEARS 64    
 7 ID726 blind    67 YEARS 67    
 8 ID864 blind    35 YEARS 37    
 9 ID864 blind    35 YEARS 37    
10 ID864 notblind 35 YEARS 67 
  

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

Так, например:

ID961 — TYPE все тот же, AGE все то же самое, AGEU все то же самое, но AVISIT не то же самое.

ID726 — TYPE все тот же, AGE все то же самое, AGEU все то же самое, но AVISIT не то же самое.

ID864 — AGE все тот же, AGEU все то же самое, но AVISIT не то же самое и TYPE не совпадает.

Поэтому я хочу, чтобы было возвращено, что AGE и AGEU все одинаковы в пределах этого идентификатора, например:

 uniform
[1] "AGE"  "AGEU"
  

Я понятия не имею, как это сделать — я понимаю, что могу использовать

 match <- df %>% group_by(ID)
  

Но тогда не знаю, как продвигаться дальше.

Ответ №1:

Возможно, вы можете сделать:

 library(dplyr)

df %>%
  group_by(ID) %>%
  summarise(across(everything(), ~ n_distinct(.x) == 1), .groups = "drop")

# Or deprecated way
df %>%
  group_by(ID) %>%
  summarise_all(~n_distinct(.x) == 1)

# A tibble: 3 x 5
  ID    TYPE  AGE   AGEU  AVISIT
  <chr> <lgl> <lgl> <lgl> <lgl> 
1 ID726 TRUE  TRUE  TRUE  FALSE 
2 ID864 FALSE TRUE  TRUE  FALSE 
3 ID961 TRUE  TRUE  TRUE  FALSE 
  

И если вам нужны имена столбцов, вы можете сделать:

 df %>%
  group_by(ID) %>%
  summarise(across(everything(), ~ n_distinct(.x) == 1), .groups = "drop") %>%
  rowwise() %>%
  transmute(ID, uniform = toString(names(.)[which(c_across(cols = -ID))   1]))

# Or ...
df %>%
  group_by(ID) %>%
  summarise_all(~n_distinct(.x) == 1)  %>%
  transmute(ID, 
            uniform = pmap_chr(.[-1], ~ toString(names(df)[c(FALSE, ...)])))  

# A tibble: 3 x 2
# Rowwise: 
  ID    uniform        
  <chr> <chr>          
1 ID726 TYPE, AGE, AGEU
2 ID864 AGE, AGEU      
3 ID961 TYPE, AGE, AGEU
  

Комментарии:

1. Я получаю сообщение об ошибке: Ошибка в across(everything(), ~ n_distinct (.x) == 1): не удалось найти функцию «across»

2. Вам необходимо обновить dplyr. across() был введен в версии 1.0.0

3. Поскольку вы не можете обновить dplyr, альтернативные способы см. в разделе Редактировать