#r #dplyr #grouping #sequence
#r #dplyr #группировка #последовательность
Вопрос:
Какой наиболее эффективный способ создать новую переменную, которая увеличивается на x единиц после каждых x строк? Например, у меня есть фрейм данных:
d <- data.frame(group_var = c('a', 'b', 'c'),
y = c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21))
И я хотел бы создать новую переменную, которая начинается с x и увеличивается на x каждые x строк, чтобы я получил такой фрейм данных:
d <- data.frame(group_var = c('a', 'b', 'c'),
y = c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21),
z = c(5,5,5,5,5,10,10,10,10,10,15,15,15,15,15,20,20,20,20,20,20,5,5,5,5,5,10,10,10,10,10,15,15,15,15,15,20,20,20,20,20,20,5,5,5,5,5,10,10,10,10,10,15,15,15,15,15,20,20,20,20,20,20))
Кроме того, когда у меня есть остатки, как и в предыдущем фрейме данных, я бы хотел, чтобы они были упорядочены с предыдущей группой (так что y = 11 будет z = 10). Обратите внимание, что мой целевой фрейм данных сохраняет то же количество строк, что и исходный фрейм данных.
Ответ №1:
Мы можем создать группирующую переменную diff
на основе on ‘y’, затем создать ‘z’ с gl
помощью и умножить на 5
library(dplyr)
library(tidyr)
d1 <- d %>%
group_by(grp = cumsum(c(TRUE, diff(y) < 0))) %>%
mutate(z = as.integer(gl(n(), 5, n())) * 5,
z = replace(z, ave(z, z, FUN = length) < 5, NA)) %>%
ungroup %>%
fill(z) %>%
select(-grp)
-вывод
as.data.frame(d1)
group_var y z
1 a 1 5
2 b 2 5
3 c 3 5
4 a 4 5
5 b 5 5
6 c 6 10
7 a 7 10
8 b 8 10
9 c 9 10
10 a 10 10
11 b 11 15
12 c 12 15
13 a 13 15
14 b 14 15
15 c 15 15
16 a 16 20
17 b 17 20
18 c 18 20
19 a 19 20
20 b 20 20
21 c 21 20
22 a 1 5
23 b 2 5
24 c 3 5
25 a 4 5
26 b 5 5
27 c 6 10
28 a 7 10
29 b 8 10
30 c 9 10
31 a 10 10
32 b 11 15
33 c 12 15
34 a 13 15
35 b 14 15
36 c 15 15
37 a 16 20
38 b 17 20
39 c 18 20
40 a 19 20
41 b 20 20
42 c 21 20
43 a 1 5
44 b 2 5
45 c 3 5
46 a 4 5
47 b 5 5
48 c 6 10
49 a 7 10
50 b 8 10
51 c 9 10
52 a 10 10
53 b 11 15
54 c 12 15
55 a 13 15
56 b 14 15
57 c 15 15
58 a 16 20
59 b 17 20
60 c 18 20
61 a 19 20
62 b 20 20
63 c 21 20
Комментарии:
1. В идеале я хотел бы автоматизировать это вместо жесткого кодирования повторений, поскольку реальный фрейм данных намного, намного больше.
2. Да, но это пример фрейма данных. В реальном фрейме данных y может достигать 200 в зависимости от идентификатора group_var . Поэтому я не хочу вручную кодировать 5, 10, 15, 20 и т.д.
3. Это был пример фрейма данных. Я отредактировал ее так, чтобы z увеличилось до 15 или 20. Я хотел автоматизировать этот процесс, поэтому я обратился за помощью.
4. Хорошо, опять же, я не хочу жестко кодировать приращения. Каждые 5 строк я хотел бы добавить 5 к y, независимо от того, сколько строк в сгруппированной переменной. Поэтому я не просто хочу написать вектор из 5, 10, 15, 20.
5. Потому что есть остаток, о котором я также спрашивал в исходном вопросе. 21 строка = последняя строка будет сгруппирована с предыдущим значением y.