#r
#r
Вопрос:
В приведенных ниже данных я хочу увеличивать значения ячеек после каждого 1, но сбрасывать его на ноль в следующей ячейке, если Z.out = 1. Вот пример.
Начальные данные:
Z B_1 C_1 D_1 E_1 F_1
0 0 0 0 0 0
0 1 0 0 1 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 1
0 1 0 0 0 0
0 0 1 1 0 0
0 0 0 1 0 0
0 1 0 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
1 0 0 0 0 0
0 0 0 0 1 0
0 0 0 0 0 0
Желаемый результат:
Z B_1 C_1 D_1 E_1 F_1
0 0 0 0 0 0
0 1 0 0 1 0
0 1 0 0 1 0
0 1 0 0 1 0
0 1 0 0 1 0
0 1 1 0 1 0
0 1 1 0 1 0
1 1 1 0 1 0
0 0 0 0 0 1
0 1 0 0 0 1
0 1 1 1 0 1
0 1 1 2 0 1
0 2 1 3 0 1
0 2 1 3 0 1
0 2 1 3 0 1
0 2 1 3 0 1
1 2 1 3 0 1
0 0 0 0 1 0
0 0 0 0 1 0
Я думаю, что могу использовать df <- df %>% transmute_at(vars(contains(«_1»)),) чтобы настроить таргетинг на нужные столбцы и заменить их желаемым результатом, но я не нашел правильного синтаксиса для функциональной части transmute . Я пытаюсь использовать cumsum() для переноса значений по каждому столбцу, но когда я пытаюсь перевернуть обратно на основе z.out, я просто заканчиваю с ошибками.
Спасибо за помощь!
Ответ №1:
Одной dplyr
из возможностей может быть:
df %>%
group_by(grp = cumsum(Z == 0 amp; lag(Z, default = first(Z)) == 1)) %>%
mutate(across(-Z, cumsum))
Z B_1 C_1 D_1 E_1 F_1 grp
<int> <int> <int> <int> <int> <int> <int>
1 0 0 0 0 0 0 0
2 0 1 0 0 1 0 0
3 0 1 0 0 1 0 0
4 0 1 0 0 1 0 0
5 0 1 0 0 1 0 0
6 0 1 1 0 1 0 0
7 0 1 1 0 1 0 0
8 1 1 1 0 1 0 0
9 0 0 0 0 0 1 1
10 0 1 0 0 0 1 1
11 0 1 1 1 0 1 1
12 0 1 1 2 0 1 1
13 0 2 1 3 0 1 1
14 0 2 1 3 0 1 1
15 0 2 1 3 0 1 1
16 0 2 1 3 0 1 1
17 1 2 1 3 0 1 1
18 0 0 0 0 1 0 2
19 0 0 0 0 1 0 2
Комментарии:
1. Итак, это работает для приведенного примера, но когда
mutate(across(-Z, cumsum)
вы исключаете только Z по имени. Что, если я хочу исключить любое количество других столбцов? или я бы просто как-то включил целевые столбцы A_1 — F1?2. Я не знаю ваш реальный набор данных, но вы можете включать / исключать переменные, используя помощники выбора, такие как
starts_with()
илиends_with()
.3. Спасибо, я просто немного поиграл с этим и попросил пользователя
contains("_1")
сделать это, и, похоже, это сработало. Приветствия!
Ответ №2:
Аналогично подходу tmfmnk, также работает следующее:
df %>%
group_by(grp = c(0, lag(cumsum(diff(Z) == 1), 1, 0))) %>%
mutate(across(-Z, cumsum)) %>%
ungroup()