#r #data.table
#r #data.table
Вопрос:
У меня есть простая data.table следующим образом
structure(list(A = c(4L, 4L, 4L, 4L, 4L, 4L, 4L, 2L, 2L, 2L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 1L, 1L, 1L, 1L, 1L),
B = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0)), class = c("data.table", "data.frame"), row.names = c(NA,
-41L), .internal.selfref = <pointer: 0x561c95850b70>)
который выглядит как —
A B
1: 4 0
2: 4 0
3: 4 0
4: 4 0
5: 4 0
6: 4 0
7: 4 0
8: 2 0
9: 2 0
10: 2 0
11: 1 0
12: 1 0
13: 1 -1
14: 1 0
15: 1 0
16: 1 0
17: 1 0
18: 1 0
19: 1 0
20: 1 0
21: 1 0
22: 1 0
23: 1 0
24: 1 0
25: 1 0
26: 1 0
27: 1 0
28: 1 0
29: 1 0
30: 3 0
31: 3 0
32: 3 0
33: 3 0
34: 3 0
35: 4 0
36: 4 0
37: 1 0
38: 1 0
39: 1 0
40: 1 0
41: 1 0
В столбце A я хочу заменить значения всей группы значениями от 1 до 6 только тогда, когда любое значение в столбце B не равно 0.
Вот желаемый результат —
A B
1: 4 0
2: 4 0
3: 4 0
4: 4 0
5: 4 0
6: 4 0
7: 4 0
8: 2 0
9: 2 0
10: 2 0
11: 6 0
12: 6 0
13: 6 -1
14: 6 0
15: 6 0
16: 6 0
17: 6 0
18: 6 0
19: 6 0
20: 6 0
21: 6 0
22: 6 0
23: 6 0
24: 6 0
25: 6 0
26: 6 0
27: 6 0
28: 6 0
29: 6 0
30: 3 0
31: 3 0
32: 3 0
33: 3 0
34: 3 0
35: 4 0
36: 4 0
37: 1 0
38: 1 0
39: 1 0
40: 1 0
41: 1 0
Я перепробовал много способов решить эту проблему с помощью data.table, но, похоже, ничего не работает. Следующее просто изменяет значения всех групп из 1, что неверно.
t[, A := ifelse(any(B != 0 amp; A == 1), 6, A), by = A]
Должен быть простой и аккуратный способ сделать это в одной строке, используя data.table
Заранее спасибо
Ответ №1:
Вот подход с rleid
:
data[,.(A = fifelse(rep(any(B!=0),.N) amp; A == 1, 6 , A), B), by = rleid(A)][,.(A,B)]