удалить дубликаты из фрагментов строк на основе одной группы в data.frame - PullRequest
0 голосов
/ 13 апреля 2019

Мне нужно удалить дублирующиеся строки на основе одной группы в пределах data.frame.

В приведенном ниже примере каждую группу из 'a' наблюдений (> 1) необходимо сократить до одного наблюдения, которое должно быть с более низким значением time:

df_1 = data.frame(time = c(1,2,8,12,19,22,23,30), group = 'a')

df_2 = data.frame(time = c(4,5,6,15,16,18,21,24,25,27), group = 'b')

df = rbind(df_1, df_2)

> df
   time group
1     1     a
2     2     a
3     4     b
4     5     b
5     6     b
6     8     a
7    12     a
8    15     b
9    16     b
10   18     b
11   19     a
12   21     b
13   22     a
14   23     a
15   24     b
16   25     b
17   27     b
18   30     a

Вот мой ожидаемый результат:

   time group
1     1     a
3     4     b
4     5     b
5     6     b
6     8     a
8    15     b
9    16     b
10   18     b
11   19     a
12   21     b
13   22     a
15   24     b
16   25     b
17   27     b
18   30     a

Любое предложение?

спасибо

Ответы [ 2 ]

2 голосов
/ 13 апреля 2019

Мы можем разделить group с помощью rleid из data.table, if group, равным a, а затем вернуть минимальное значение time, для группы b вернуть всю группу как есть.,

library(tidyverse)
library(data.table)

df %>%
  group_split(rleid(group), keep = FALSE) %>%
  map_dfr(~ if(.$group[1] == 'a') .[which.min(.$time), ] else .)


#    time group
#   <int> <fct>
# 1     1 a    
# 2     4 b    
# 3     5 b    
# 4     6 b    
# 5     8 a    
# 6    15 b    
# 7    16 b    
# 8    18 b    
# 9    19 a    
#10    21 b    
#11    22 a    
#12    24 b    
#13    25 b    
#14    27 b    
#15    30 a    
0 голосов
/ 13 апреля 2019

Мы можем сделать это намного проще с data.table.Просто сгруппируйте по идентификатору длины прогона 'group' (rleid), order 'time' в i, получите строку индекса (.I) элементов, которые не duplicated, где«группа» - это «а» или «б».Используйте это для подмножества строк

library(data.table)
i1 <- setDT(df)[order(time), .I[!duplicated(group == 'a')|
        group == 'b'] , .(grp = rleid(group))]$V1
df[i1]
#    time group
# 1:    1     a
# 2:    4     b
# 3:    5     b
# 4:    6     b
# 5:    8     a
# 6:   15     b
# 7:   16     b
# 8:   18     b
# 9:   19     a
#10:   21     b
#11:   22     a
#12:   24     b
#13:   25     b
#14:   27     b
#15:   30     a

ПРИМЕЧАНИЕ. Нет if/else или не требуется зацикливание

data

df <- structure(list(time = c(1L, 2L, 4L, 5L, 6L, 8L, 12L, 15L, 16L, 
18L, 19L, 21L, 22L, 23L, 24L, 25L, 27L, 30L), group = c("a", 
 "a", "b", "b", "b", "a", "a", "b", "b", "b", "a", "b", "a", "a", 
 "b", "b", "b", "a")), class = "data.frame", row.names = c("1", 
 "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
  "14", "15", "16", "17", "18"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...