как получить первое значение и последние три значения определенной группы - PullRequest
1 голос
/ 30 апреля 2020

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

data[,c(.SD[1,] , .SD[2,]),by=c("id","status","group")]

Теперь вместо первый и последний, я хочу взять первые и последние три записи по группировке.

Любая помощь приветствуется.

Ответы [ 5 ]

4 голосов
/ 30 апреля 2020

Я думаю, head и tail будут безопаснее и будут использовать уникальные значения один раз для индексов, как упомянуто sindri_baldur:

k <- 3L
DT[unique(DT[, c(head(.I, k), tail(.I, k)), id]$V1)]

вывод:

    id VAL
 1:  1   1
 2:  1   2
 3:  1   3
 4:  1   5
 5:  1   6
 6:  1   7
 7:  2   8
 8:  2   9
 9:  2  10
10:  2  11
11:  2  12
12:  2  13
13:  3  14
14:  3  15
15:  3  16
16:  3  17
17:  3  18
18:  4  19
19:  4  20
20:  4  21
21:  4  22
22:  5  23
23:  5  24
24:  5  25
25:  6  26
26:  6  27
27:  7  28
    id VAL

данные:

library(data.table)
x <- sort(sequence(7:1))
DT <- data.table(id=x, VAL=1:length(x))
4 голосов
/ 30 апреля 2020

быстро и грязно

#sample data
DT <- data.table( id = 1:2, value = 1:100 )
#code
DT[, .SD[ c( 1:3, .N-2, .N-1, .N ) ], by = .(id) ]

#output
#    id value
# 1:  1     1
# 2:  1     3
# 3:  1     5
# 4:  1    95
# 5:  1    97
# 6:  1    99
# 7:  2     2
# 8:  2     4
# 9:  2     6
# 10: 2    96
# 11: 2    98
# 12: 2   100
1 голос
/ 02 мая 2020

Используя данные @ chinsoon12, вот еще один способ:

k = 3L
max_grp = 2L * k

init_seq = seq_len(k)
k_minus_one = k - 1L

DT[DT[, if (.N <=max_grp) .I else .I[c(init_seq, (.N-k_minus_one):.N)], by = x]$V1]

Этот ответ хорошо масштабируется, но определенно является бельмом на глазу.

0 голосов
/ 30 апреля 2020

Вот решение dplyr::filter для получения 1-й, 3-й и 3-х последних записей в каждой группе:

data %>% 
  group_by(id, status, group) %>%
  filter(row_number() %in% c(1:3, (n()-2):n())) 
0 голосов
/ 30 апреля 2020

Одно решение с использованием dplyr может быть

data %>% 
  group_by(id, status, group) %>% 
  slice(c(1:3, (n()-2):n()))

Пример с набором данных iris

iris %>% 
  group_by(Species) %>% 
  slice(c(1:3, (n()-2):n()))

Вывод

# A tibble: 18 x 5
# Groups:   Species [3]
#    Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#           <dbl>       <dbl>        <dbl>       <dbl> <fct>     
#  1          5.1         3.5          1.4         0.2 setosa    
#  2          4.9         3            1.4         0.2 setosa    
#  3          4.7         3.2          1.3         0.2 setosa    
#  4          4.6         3.2          1.4         0.2 setosa    
#  5          5.3         3.7          1.5         0.2 setosa    
#  6          5           3.3          1.4         0.2 setosa    
#  7          7           3.2          4.7         1.4 versicolor
#  8          6.4         3.2          4.5         1.5 versicolor
#  9          6.9         3.1          4.9         1.5 versicolor
# 10          6.2         2.9          4.3         1.3 versicolor
# 11          5.1         2.5          3           1.1 versicolor
# 12          5.7         2.8          4.1         1.3 versicolor
# 13          6.3         3.3          6           2.5 virginica 
# 14          5.8         2.7          5.1         1.9 virginica 
# 15          7.1         3            5.9         2.1 virginica 
# 16          6.5         3            5.2         2   virginica 
# 17          6.2         3.4          5.4         2.3 virginica 
# 18          5.9         3            5.1         1.8 virginica 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...