Выполнение операций над сводками dplyr

#r #dplyr #summarize

Вопрос:

Предположим, у нас есть какие-то случайные данные:

 data <- data.frame(ID = rep(seq(1:3),3),
                   Var = sample(1:9, 9))
 

мы можем вычислить операции суммирования , используя dplyr , например,:

 library(dplyr)
data%>%
  group_by(ID)%>%
  summarize(count = n_distinct(Var))
 

что дает результат, который выглядит следующим образом ниже уценки r:

 ID count
1   3           
2   3           
3   3   
 

Я хотел бы знать, как мы можем выполнять операции с отдельными точками данных в этом dplyr выводе, не сохраняя вывод в отдельном объекте.

Например , в выводе summarise , допустим, мы хотели вычесть выходное значение для ID == 3 из суммы выходных значений для ID == 1 и ID == 2 и оставить выходные значения для ID == 1 и ID == 2 такими, какие они есть. Единственный известный мне способ сделать это-сохранить итоговый вывод в другом объекте и выполнить операцию над этим объектом, как это:

 a<-
  data%>%
  group_by(ID)%>%
  summarize(count = n_distinct(Var))
a
#now perform the operation on a
a[3,2] <- a[2,1] a[2,2]-1
a
 

a теперь выглядит так:

 ID count
1   3           
2   3           
3   4
 

Есть ли способ сделать это в dplyr выводе без создания новых объектов? Можем ли мы как-то использовать mutate непосредственно на выходе, как это?

Комментарии:

1. a[2,1] a[2,2]-1 для меня не имеет смысла: почему вы добавляете ID в count ? Почему вы используете матричную индексацию вместо индексации кадров (т. Е. по имени)?

2. Я также повторяю комментарий r2evans. Сначала я подумал, что это будут все строки, кроме последней. Но тогда ваш результат был бы другим

3. Вы правы, мой пример не имеет логического смысла, сначала это была опечатка, но, тем не менее, он все еще работал как эффективный пример для моего вопроса о том, как выполнять операции в отдельных местах в выводе, поэтому я решил оставить все как было

Ответ №1:

Мы можем добавить a mutate после summarise с replace , чтобы изменить местоположение, указанное в list

 library(dplyr)
data%>%
   group_by(ID)%>%
   summarize(count = n_distinct(Var)) %>% 
   mutate(count = replace(count, n(), count[2]   ID[2] - 1))
 

-выход

 # A tibble: 3 x 2
     ID count
  <int> <dbl>
1     1     3
2     2     3
3     3     4
 

Или, если столбцов больше двух, используйте sum в строке slice d

 data%>%
   group_by(ID)%>%
   summarize(count = n_distinct(Var)) %>% 
   mutate(count = replace(count, n(), sum(cur_data() %>% 
          slice(2)) - 1))
 

Ответ №2:

Альтернатива, которая делает то, что вы говорите, что хотите («суммируйте других»), но не то, что вы демонстрируете.

 data %>%
  group_by(ID) %>%
  summarize(count = n_distinct(Var)) %>%
  mutate(count = if_else(ID == 3L, sum(count) - count, count))
# # A tibble: 3 x 2
#      ID count
#   <int> <int>
# 1     1     3
# 2     2     3
# 3     3     6
 

или, если есть другие ID s, которые не должны быть включены в сумму, то

 data %>%
  group_by(ID) %>%
  summarize(count = n_distinct(Var)) %>%
  mutate(count = if_else(ID == 3L, sum(count[ID %in% 1:2]), count))