Dplyr: групповое вычитание значений (на основе предварительно отфильтрованных строк)

Я застрял на (вероятно) очень очевидной вещи, но я не могу понять, в чем настоящая проблема.

DF <- data.frame(Gene = c(rep("A",8), rep("X",8)),
             Genotype = c(rep("WT",4),rep("mut",4),rep("WT",4),rep("mut",4)),
             TimePoint = c(1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4),
             Value = c(12.5,12.33,11,10,23.22,22,21.2,45.3,22,12,23,21.2,23.2,45.3,21,22))

Что я хочу сделать: Вычтите значение, соответствующее TimePoint == 1, из всех значений в группе (здесь: Группа = Ген, Генотип).

Я хотел бы, чтобы результат был таким, как показано здесь:

DF %>% group_by(Gene, Genotype) %>% mutate(Diff = Value - first(Value))

Однако вместо первой функции я бы выбрал значение на основе заданной точки времени, которая не обязательно должна быть первой в каждой группе.

Моя идея заключалась в том, чтобы сделать что-то подобное, но на самом деле он не использует сгруппированные данные, как ожидалось:

DF %>% group_by(Gene, Genotype) %>% mutate(Diff = Value - filter(.,TimePoint == 1)$Value)

Я действительно не знаю, почему сгруппированные данные неправильно передаются в оператор фильтра?

4
0
840
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После этапа группирования подмножество «Value», создав логический вектор с «TimePoint», то есть TimePoint == 1, и вычтите его из «Value».

DF %>%
   group_by(Gene, Genotype) %>%
   mutate((Diff = Value - Value[TimePoint == 1]))

Или другой вариант - match для получения индекса

DF %>%
   group_by(Gene, Genotype) %>% 
   mutate((Diff = Value - Value[match(1, TimePoint)]))

Если нам действительно нужно использовать filter, отфильтруйте набор данных, затем выполните right_join и получите разницу.

DF %>%
   filter(TimePoint == 1) %>% 
   select(Gene, Genotype, Value1 = Value)  %>% 
   right_join(DF) %>% 
   mutate(Diff = Value - Value1) %>%
   select(-Value1)

В способе OP filter, извлеченном из «Value» после filter, не соблюдаются ограничения group_by, а только вычитается путем повторного использования.

Большое спасибо :) Есть ли способ использовать в этом случае «фильтр» вместо «базового» синтаксиса. Моя главная проблема заключалась также в том, чтобы понять, почему здесь не работает фильтр.

interrobang 11.04.2018 13:54

@interrobang Одно из главных достоинств pipe - облегчить чтение потока. Вложение нескольких функций в канал затрудняет чтение

akrun 11.04.2018 14:07

@count Это уже есть в сообщении OP. Я думаю, что OP хотел сделать filtering на основе TimePoint.

akrun 11.04.2018 14:11

Другие вопросы по теме