Удалить дублирующуюся группу dplyr r

#r #dataframe #dplyr #group-by

Вопрос:

У меня есть следующий фрейм данных:

 df <- structure(list(GENE= c("ENS1", "ENS2", 
"ENS3", "ENS4", "ENS1",  "ENS2", "ENS3"), group= c(1L, 
1L, 1L, 2L, 3L, 3L, 3L)), 
class = "data.frame", row.names = c(NA, -7L))

GENE  group
ENS1  1
ENS2  1
ENS3  1
ENS4  2
ENS1  3
ENS2  3
ENS3  3
 

Поскольку группы 1 и 3 идентичны, я хотел бы удалить одну из них.
Как я могу это сделать?

Спасибо

Ответ №1:

Базовый вариант R с использованием stack unstack duplicated

 setNames(
    type.convert(
        stack((u <- unstack(df))[!duplicated(u)]),
        as.is = TRUE
    ), names(df)
)
 

что дает

   GENE group
1 ENS1     1
2 ENS2     1
3 ENS3     1
4 ENS4     2
 

Ответ №2:

 library(dplyr)
distinct(df, GENE, .keep_all = TRUE)
 

Выход:

   GENE group
1 ENS1     1
2 ENS2     1
3 ENS3     1
4 ENS4     2
 

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

1. Это работает только для данного примера. При удалении строки 7 из входной df <- df[-7, ] группы 1 и 3 не идентичны, но она все равно удалит группу 3.

Ответ №3:

Мы могли бы использовать filter с !duplicated :

 library(dplyr)

  df %>% 
    filter(!duplicated(GENE))
 

Выход:

   GENE group
1 ENS1     1
2 ENS2     1
3 ENS3     1
4 ENS4     2
 

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

1. Это работает только для данного примера. При удалении строки 7 из входной df <- df[-7, ] группы 1 и 3 не идентичны, но она все равно удалит группу 3.

2. @Ronak Shah. Спасибо вам за этот совет. Лучшая информация, как всегда!

Ответ №4:

Вы можете создать уникальный key , вставив GENE значение для всех group вместе, оставив в выводе только уникальные ключи, присоединившись к оригиналу df .

 library(dplyr)

df %>%
  group_by(group) %>%
  summarise(key = toString(sort(GENE))) %>%
  distinct(key, .keep_all = TRUE) %>%
  left_join(df, by = 'group') %>%
  select(-key)

df

#  group GENE 
#  <int> <chr>
#1     1 ENS1 
#2     1 ENS2 
#3     1 ENS3 
#4     2 ENS4 
 

Если вы удалите 7-ю строку в данных, чтобы группы 1 и 3 не были идентичными, она сохранит строки для всех групп. Я надеюсь, что это то, что вы имели в виду под «идентичным».

 df <- df[-7, ]

df %>%
  group_by(group) %>%
  summarise(key = toString(sort(GENE))) %>%
  distinct(key, .keep_all = TRUE) %>%
  left_join(df, by = 'group') %>%
  select(-key)

#  group GENE 
#  <int> <chr>
#1     1 ENS1 
#2     1 ENS2 
#3     1 ENS3 
#4     2 ENS4 
#5     3 ENS1 
#6     3 ENS2 
 

Ответ №5:

С помощью base R

 subset(df, !duplicated(GENE))
  GENE group
1 ENS1     1
2 ENS2     1
3 ENS3     1
4 ENS4     2
 

Ответ №6:

Вы можете выбрать split группу и выбрать элементы списка, которых нет в duplicated ГЕНЕ, и rbind результат.

 x <- unname(split(df, df$group))
do.call(rbind, x[!duplicated(lapply(x, `[[`, "GENE"))])
#  GENE group
#1 ENS1     1
#2 ENS2     1
#3 ENS3     1
#4 ENS4     2
 

В случае, если ГЕН не уникален и отсортирован в каждой группе, это необходимо сделать дополнительно, чтобы можно было обнаружить дубликаты.

 x <- unname(split(df, df$group))
do.call(rbind, x[!duplicated(lapply(x, function(y) sort(unique(y$GENE))))])
#  GENE group
#1 ENS1     1
#2 ENS2     1
#3 ENS3     1
#4 ENS4     2