#r #dataframe
#r #фрейм данных
Вопрос:
У меня есть фрейм данных:
DF <- data.frame(Observation = c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17),
ID = c('A','A','B','C','D','D','B','B','B','B','A','A','A','B','D','D','C'),
Group = c('X1','X2','X1','X1','X2','X2','X2','X1','X1','X2','X2','X2','X2','X1','X2','X1','X1'),
Value = c(1,0,1,0,0,1,1,1,0,0,1,1,0,1,0,1,1))
Я хотел бы получить совокупную сумму по «идентификатору» (не сложно), но только на основе соответствующих последних значений «Группы», частью которой является каждый идентификатор. Другими словами: для каждого «идентификатора» создайте совокупную сумму для всех последних доступных значений тех «групп», где присутствует идентификатор (может включать текущее значение в заданной строке с учетом ссылки на последнее доступное значение).
Подробное объяснение: пример для ID = A:
In ( 1
) ID
= A
ссылается на X1
in ( 1
) со значением = 1
, приводит к cum_sum = 1
.
In ( 2
) ID
= A
ссылается на X1
in ( 1
) со значением = 1
и X2
in ( 2
) со значением = 0
, приводит к cum_sum = 1
.
In ( 11
) ID
= A
ссылается на X1
in ( 1
) со значением = 1
и X2
in ( 11
) со значением = 1
, приводит к cum_sum = 2
.
In ( 12
) ID
= A
ссылается на X1
in ( 1
) со значением = 1
и X2
in ( 12
) со значением = 1
, приводит к cum_sum = 2
.
In ( 13
) ID
= A
ссылается на X1
in ( 1
) со значением = 1
и X2
in ( 13
) со значением = 0
, приводит к cum_sum = 1
.
Конечный результат выглядит следующим образом.
DF_Result <- data.frame(Observation = c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17),
ID = c('A','A','B','C','D','D','B','B','B','B','A','A','A','B','D','D','C'),
Group = c('X1','X2','X1','X1','X2','X2','X2','X1','X1','X2','X2','X2','X2','X1','X2','X1','X1'),
Value = c(1,0,1,0,0,1,1,1,0,0,1,1,0,1,0,1,1),
Cum_Sum = c(1,1,1,0,0,1,2,2,1,0,2,2,1,1,0,1,1))
Заранее большое вам спасибо.
Комментарии:
1. Да, пакеты и базовые функции уже известны — но это не просто кумулятивная сумма, основанная на одном идентификаторе — это кумулятивная сумма по идентификатору для каждого последнего значения группы (группы), частью которой или которой является идентификатор
2. @Ronak Shah Спасибо. Может быть (много) других групп (это упрощенный пример).
3. Я думаю, что логика не ясна, когда я смотрю на разные «идентификаторы»
4. например, для ID = «B» значение изменилось с 2 на 1 (строка с 8 по 9) — оба равны X1, а значение равно 1 и 0. Вы вычли это. Аналогично 9-10, это 0, в то время как предыдущее значение X2 равно 2
5. @akrun. Вы правы. Правильная версия: в (6) ID = D ссылается на X2 в (6) со значением = 1, приводит к cum_sum = 1. Пожалуйста, извинитесь за ошибку.
Ответ №1:
Согласен с некоторыми другими, что объяснения немного сложны для понимания… Но вот моя попытка: вы имеете в виду, что пытаетесь вычислить сумму для каждого идентификатора для каждого идентификатора и кумулятивного последнего значения для каждой группы?
Если да, то вот реализация. Хитрость заключается в том, чтобы вычислить производную для каждого идентификатора и для каждой группы (например diff()
), и они принимают ее cumsum()
для каждого идентификатора:
DF %>%
group_by(ID, Group) %>%
mutate(Diff = Value - lag(Value, default=0)) %>%
group_by(ID) %>%
mutate(Cum_Sum = cumsum(Diff))
Комментарии:
1. Спасибо, Пьер. Похоже, это работает отлично (также для N> 2 групп). В настоящее время я тестирую несколько модификаций (на данный момент это работает, как и ожидалось). Отлично!
2. Отлично. Дайте нам знать, если вам нужны какие-либо изменения
3. Да, работает с дополнительными подгруппами, а также с изменениями значения по умолчанию. Я предполагаю, что cumsum может быть заменен любой дальнейшей операцией (например, mean), верно? В любом случае, отлично!
Ответ №2:
Я согласен с мнением, выраженным в комментариях, что это неясно. Честно говоря (и я действительно не имею в виду это как оскорбление), это ужасное описание проблемы с неоднозначными / нестандартными терминами («ссылаться на») и запутанными объяснениями.
Возможно, следующее является шагом к поиску решения; оно не полностью воспроизводит ваш ожидаемый результат, но приближается. Надеюсь, вы действительно допустили ошибку в своем ожидаемом результате, потому что, честно говоря, я не могу разобраться в логике.
DF %>%
group_by(ID) %>%
mutate(
n = 1:n(),
Cum_Sum = if_else(n > 1, Value first(Value), Value)) %>%
select(-n)
## A tibble: 17 x 5
## Groups: ID [4]
# Observation ID Group Value Cum_Sum
# <dbl> <fct> <fct> <dbl> <dbl>
# 1 1 A X1 1 1
# 2 2 A X2 0 1
# 3 3 B X1 1 1
# 4 4 C X1 0 0
# 5 5 D X2 0 0
# 6 6 D X2 1 1
# 7 7 B X2 1 2
# 8 8 B X1 1 2
# 9 9 B X1 0 1
#10 10 B X2 0 1
#11 11 A X2 1 2
#12 12 A X2 1 2
#13 13 A X2 0 1
#14 14 B X1 1 2
#15 15 D X2 0 0
#16 16 D X1 1 1
#17 17 C X1 1 1
Я перевел вашу постановку задачи следующим образом: Cum_Sum
это сумма текущего Value
и первого значения в этом Group
; если текущее значение является первым значением, Cum_Sum
это просто текущее Value
.
Первые 9 строк идентичны вашему ожидаемому результату; Я понятия не имею, почему Cum_Sum
для строки 10 равно 0…
Обновить
Надеюсь, приближаясь к тому, что вы пытаетесь сделать
DF %>%
group_by(ID) %>%
mutate(Cum_Sum = Value lag(Value, default = 0))
## A tibble: 17 x 5
## Groups: ID [4]
# Observation ID Group Value Cum_Sum
# <dbl> <fct> <fct> <dbl> <dbl>
# 1 1 A X1 1 1
# 2 2 A X2 0 1
# 3 3 B X1 1 1
# 4 4 C X1 0 0
# 5 5 D X2 0 0
# 6 6 D X2 1 1
# 7 7 B X2 1 2
# 8 8 B X1 1 2
# 9 9 B X1 0 1
#10 10 B X2 0 0
#11 11 A X2 1 1
#12 12 A X2 1 2
#13 13 A X2 0 1
#14 14 B X1 1 1
#15 15 D X2 0 1
#16 16 D X1 1 1
#17 17 C X1 1 1
При условии, что я правильно понял вашу «логику», это действительно не имеет ничего общего с кумулятивной суммой; вместо этого это просто
за ID
.
Если вы хотите сделать это за ID
и за Group
, просто замените group_by(ID)
на group_by(ID, Group)
.
Комментарии:
1. Значение в позиции 10 равно 0 вместо 1 (на основе
DF_Result
2. @akrun Да, к сожалению:-) Я понятия не имею, почему (см. Последнее предложение моего поста)… надеемся, что OP допустил ошибку или, возможно, это поможет прояснить проблему.
3. Кроме того, для 14 у меня есть сомнения, которые я высказал в комментариях
4. Спасибо. Пожалуйста, прочитайте примеры, которые я разместил под исходными сообщениями: В (10) ID = B относится к X1 в (9) со значением = 0 и X2 в (10) со значением = 0, приводит к cum_sum = 0. В (14) ID = B относится к X1 в (14) со значением = 1 и X2 в (10) со значением = 0, приводит к cum_sum = 1. (Всегда последнее доступное значение для соответствующих подгрупп).
5. @Dan Да, конечно, но вашим комментариям несколько не хватает конкретной логики, которую нам нужно понять. Подумайте об этом. 4-5 человек пытались это сделать (и многие другие, не признавая). Итак, было бы неплохо сформулировать логику немного иначе