У меня есть набор данных в R, похожий на этот
дф
day team data
1 A 5
1 B 2
1 C 1
2 A 2
2 B 3
2 C 1
3 A 0
3 B 2
3 C 1
... ... ...
Теперь я хочу вычислить среднее значение данных условно на основе day
и team
, которые должны быть добавлены к каждой строке в наборе данных. Среднее значение рассчитывается на основе команды и всех предыдущих строк, где день находится в определенном диапазоне по сравнению со днем в строке. Диапазон должен определяться переменной.
Например, если range <- 2
среднее значение должно рассчитываться для каждой команды следующим образом:
day team data mean
1 A 5 5
1 B 2 2
1 C 1 1
2 A 2 3.5
2 B 3 2.5
2 C 1 1
3 A 0 1
3 B 2 2.5
3 C 1 1
... ... ... ...
Как я могу добиться этого, например, с помощью aggregate()
?
Обычно это называется «скользящим средним» или «скользящим средним». Вот несколько вопросов с ответами для этого: Скользящее среднее/скользящее среднее с dplyr , Скользящее среднее (скользящее среднее) по группе , Скользящее среднее значение по группе.
@GregorThomas Черт, ты прав. Так просто, как, что. Я ищу скользящее среднее по группе. Это значительно упрощает поиск. Спасибо.
Если вам нужно использовать aggregate
, сначала убедитесь, что данные отсортированы по day
, как указано выше, а затем выполните:
n <- 2
aggregate(df, data~team, \(x)rowMeans(embed(c(rep(NA, n-1), x), n), na.rm = TRUE))
team data.1 data.2 data.3
1 A 5.0 3.5 1.0
2 B 2.0 2.5 2.5
3 C 1.0 1.0 1.0
Если вы хотите, чтобы это было в формате, указанном выше, используя базу R:
df|>
aggregate(data~team, \(x)rowMeans(embed(c(rep(NA, n-1), x), n), na.rm = TRUE))|>
do.call(what = data.frame)|>
reshape(-1,dir='long', idvar = 'team', timevar = 'day', new.row.names = rownames(df))
team day data
1 A 1 5.0
2 B 1 2.0
3 C 1 1.0
4 A 2 3.5
5 B 2 2.5
6 C 2 1.0
7 A 3 1.0
8 B 3 2.5
9 C 3 1.0
Судя по комментариям выше, решение оказалось проще, чем ожидалось, путем расчета скользящего среднего с пакетом zoo
следующим образом.
Первый заказ и группировка данных по команде и дню
df <- df[order(df$team, df$day), ]
df <- group_by(df, team)
Затем добавляем скользящее среднее
df <- mutate(df, moving_avg2 =rollmean(team, k=2, fill=NA, align='right'))
Это можно компактно записать так: library(dplyr); library(zoo); df %>% arrange(team, day) %>% mutate(ma = rollmeanr(data, 2, fill = NA), .by = team)
. Обратите внимание на букву r в конце rollmeanr
, чтобы получить правильное выравнивание.
Похоже, вам нужно скользящее среднее. См. stackoverflow.com/questions/26198551/…. Есть ли у вас пробелы в распорядке дня, которые вам нужно учитывать?