Столбец суммы по определенным номерам строк в сгруппированном фрейме данных в R

#r #dataframe #dplyr

Вопрос:

У меня есть фрейм данных, подобный этому:

 df = data.frame(
  x = 1:100,
  y = rep(1:10, times = 10, each = 10)
) %>% 
  group_by(y)
 

И я хотел бы вычислить сумму x от 3-й до 6-й строки каждой группы y .
Я думаю, что это должно быть легко, но я просто не могу понять это в данный момент.

В псевдокоде я представляю себе что-то вроде этого:

 df %>% 
  mutate(
    sum(x, ifelse(between(row_number(), 3,6)))
  )

 

Но это, конечно, не работает. Я хотел бы решить эту проблему с помощью какой dplyr -либо функции, но и в базе R я не могу придумать быстрого решения.
Для первой группы сумма будет равна 3 4 5 6 ….

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

1. df %>% summarise(x = sum(x[3:6]))

2. Классно! Но почему я могу использовать обычную индексацию здесь?

3. Что вы подразумеваете под нормальной индексацией?

4. Я имел в виду индексацию base-r с квадратными скобками

Ответ №1:

Одним из вариантов может быть:

 df %>% 
 group_by(y) %>%
 mutate(z = sum(x[row_number() %in% 3:6]))

       x     y     z
   <int> <int> <int>
 1     1     1    18
 2     2     1    18
 3     3     1    18
 4     4     1    18
 5     5     1    18
 6     6     1    18
 7     7     1    18
 8     8     1    18
 9     9     1    18
10    10     1    18
 

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

1. о, как это мило! Большое спасибо!

2. Я часто действительно путаюсь в том, какие методы подмножества разрешены, а какие нет (например, объединение base-R и dplyr, как вы сделали здесь). Так что большое вам спасибо за это:)

Ответ №2:

Вы также можете сделать это с filter() помощью и summarise() и получить групповое резюме:

 df %>% 
  group_by(y) %>% 
  mutate(rn = 1:n()) %>%
  filter(rn %in% 3:6) %>%
  summarise(x_sum = sum(x))

# A tibble: 10 x 2
       y x_sum
   <int> <int>
 1     1    18
 2     2    58
 3     3    98
 4     4   138
 5     5   178
 6     6   218
 7     7   258
 8     8   298
 9     9   338
10    10   378
 

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

1. Это, безусловно, один из вариантов. Немного представьте, если я хочу сделать это для двух разных комбинаций строк. Например, строка 3-6 и строка 1-4. Фильтрация допускает только одну комбинацию, не так ли?

2. Это правда! Кроме того, использование подхода slice() ТарДжи несколько более элегантно!

Ответ №3:

Обновление: Если вы хотите суммировать несколько последовательностей из x, то вы можете sum по индексу:

 df %>%  
  group_by(y) %>% 
  mutate(sum_row3to6 = sum(x[3:6]),
         sum_row1to4 = sum(x[1:4])
         )
 

Выход:

        x     y sum_row3to6 sum_row1to4
   <int> <int>       <int>       <int>
 1     1     1          18          10
 2     2     1          18          10
 3     3     1          18          10
 4     4     1          18          10
 5     5     1          18          10
 6     6     1          18          10
 7     7     1          18          10
 8     8     1          18          10
 9     9     1          18          10
10    10     1          18          10
 

Первый ответ:
Мы могли бы использовать slice summarise

 library(dplyr)
df %>% 
  group_by(y) %>% 
  slice(3:6) %>% 
  summarise(sum = sum(x))
 

Выход:

        y   sum
   <int> <int>
 1     1    18
 2     2    58
 3     3    98
 4     4   138
 5     5   178
 6     6   218
 7     7   258
 8     8   298
 9     9   338
10    10   378
 

Ответ №4:

данные.таблица

 library(data.table)
df = data.frame(
  x = 1:100,
  y = rep(1:10, times = 10, each = 10)
)
setDT(df)[rowid(y) %in% 3:6, list(sum_x = sum(x)), by = y][]
#>      y sum_x
#>  1:  1    18
#>  2:  2    58
#>  3:  3    98
#>  4:  4   138
#>  5:  5   178
#>  6:  6   218
#>  7:  7   258
#>  8:  8   298
#>  9:  9   338
#> 10: 10   378
 

Создано 2021-05-21 пакетом reprex (v2.0.0)