Как консолидировать строки на основе того, имеют ли они одинаковое значение в ключевом столбце?

#r #dplyr

Вопрос:

Я работаю со сценарием R, который не принимает дубликаты в определенном столбце, потому что этот столбец присваивается rownames одному из data.frame них . Однако многие строки фрейма данных, с которыми я работаю, содержат дубликаты генов ( gene_id ) и нормализованные значения экспрессии, поскольку они были секвенированы в экзонной области одного и того же гена вдоль транскриптома.

 > data.table(df) %>% 
          group_by(gene_id)
# A tibble: 138,930 x 544
# Groups:   gene_id [22,672]
   `#chr`  start    end gene_id         `XXXXX… `XXXXX…
   <fct>   <int>  <int> <fct>                          <dbl>               <dbl>
 1 chr20  290428 290429 ENSG0000019647…               0.830                2.54 
 2 chr20  290748 290749 ENSG0000019647…               0.830                2.54 
 3 chr20  290777 290778 ENSG0000019647…               0.830                2.54 
 4 chr20  296967 296968 ENSG0000024731…              -0.0533               0.308
 5 chr20  325233 325234 ENSG0000022537…              -0.299               -0.274
 6 chr20  325594 325595 ENSG0000017773…               0.246                1.98 
 7 chr20  346781 346782 ENSG0000012584…              -0.156               -1.06 
 8 chr20  346882 346883 ENSG0000012584…              -0.156               -1.06 
 9 chr20  347023 347024 ENSG0000012584…              -0.156               -1.06 
10 chr20  347104 347105 ENSG0000012584…              -0.156               -1.06 
 

Я хотел бы объединить, например, строки 1-3 и сохранить наименьшее start значение и наибольшее end значение, и получить только 1 результирующую строку. Однако я не знаю, как это сделать dplyr , кроме как начать с group_by общей колонки. Что вы предлагаете/как бы я поступил дальше?

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

1. @akrun Нет, XXXXX значения идентичны для одинаковых gene_id значений.

Ответ №1:

Мы можем использовать slice_head с n = 1 после обновления столбцов «начало», «конец» с помощью min и max (или first и last — при заказе) в сгруппированных данных

 library(dplyr)
df %>%
    group_by(gene_id) %>%
    mutate(start = min(start), end = max(end)) %>%    
    slice_head(n = 1) %>%
    ungroup 
 

Или использовать distinct

 df %>%
   group_by(gene_id) %>%
   mutate(start = min(start), end = max(end)) %>%
   ungroup %>%
   distinct(gene_id, .keep_all = TRUE)