Создайте новый столбец со средними значениями за интервалы времени

У меня есть набор данных, который начинается в 1988 году и заканчивается в 2020 году. Я хочу создать средние значения для определенных интервалов времени. Например, 5 лет: 1988-1992, 1993-1997 и так далее. Но мне нужен новый столбец с этими средними значениями.

Например, предположим, что у меня есть это:

anos <- 1988:2020
valores <- c(15, 18, 20, NA, 25, 27, 28, NA, 32, 35, 36, 38, 40, 
             42, 45, 46, NA, 50, 52, 55, 56, 58, 60, NA, 65, 66, 
             68, 70, 72, 75, 76, 78, 80)

dataset <- data.frame(Ano = anos, Valor = valores)

Я хочу иметь это:

anos <- 1988:2020

valores <- c(15, 18, 20, NA, 25, 27, 28, NA, 32, 35, 36, 38, 40, 
             42, 45, 46, NA, 50, 52, 55, 56, 58, 60, NA, 65, 66, 
             68, 70, 72, 75, 76, 78, 80)

medias <- c(19.5, 19.5, 19.5, 19.5, 19.5,
            30.5, 30.5, 30.5, 30.5, 30.5,
            40.2, 40.2, 40.2, 40.2, 40.2,
            50.75, 50.75, 50.75, 50.75, 50.75,
            59.75, 59.75, 59.75, 59.75, 59.75,
            70.2, 70.2, 70.2, 70.2, 70.2,
            78, 78, 78)
            
dataset <- data.frame(Ano = anos, Valor = valores, Medias = medias)

Для каждого временного интервала имеются средние значения за пять лет, и среднее значение повторяется до следующих пяти лет. Последнее среднее значение представляет собой среднее из трех значений, поскольку общий период не кратен пяти.

Обновлено: также мне нужно будет использовать group_by().

Что, если в группе 5 есть только NA?

s_baldur 22.07.2024 15:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
53
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Возьмите верхний остаток от деления на 5.

ave(
  dataset$Valor,
  ceiling(seq_along(rownames(dataset))/5),
  FUN=function(x){mean(x,na.rm=T)}
)

    Ano Valor Medias media
1  1988    15  19.50 19.50
2  1989    18  19.50 19.50
3  1990    20  19.50 19.50
4  1991    NA  19.50 19.50
5  1992    25  19.50 19.50
6  1993    27  30.50 30.50
7  1994    28  30.50 30.50
8  1995    NA  30.50 30.50
9  1996    32  30.50 30.50
10 1997    35  30.50 30.50
11 1998    36  40.20 40.20
12 1999    38  40.20 40.20
13 2000    40  40.20 40.20
14 2001    42  40.20 40.20
15 2002    45  40.20 40.20
16 2003    46  50.75 50.75
17 2004    NA  50.75 50.75
18 2005    50  50.75 50.75
19 2006    52  50.75 50.75
20 2007    55  50.75 50.75
21 2008    56  59.75 59.75
22 2009    58  59.75 59.75
23 2010    60  59.75 59.75
24 2011    NA  59.75 59.75
25 2012    65  59.75 59.75
26 2013    66  70.20 70.20
27 2014    68  70.20 70.20
28 2015    70  70.20 70.20
29 2016    72  70.20 70.20
30 2017    75  70.20 70.20
31 2018    76  78.00 78.00
32 2019    78  78.00 78.00
33 2020    80  78.00 78.00

База Р:

mean_every_n <- function(x, n=5L) {
  grp <- (seq_along(x) - 1 ) %/% n
  ave(x, grp, FUN = \(y) mean(y, na.rm = TRUE))
}
dataset$medias <- mean_every_5(dataset$Valor)


> head(dataset, 11)
#     Ano Valor medias
# 1  1988    15   19.5
# 2  1989    18   19.5
# 3  1990    20   19.5
# 4  1991    NA   19.5
# 5  1992    25   19.5
# 6  1993    27   30.5
# 7  1994    28   30.5
# 8  1995    NA   30.5
# 9  1996    32   30.5
# 10 1997    35   30.5
# 11 1998    36   40.2

С помощью data.table вы можете сделать следующее:

library(data.table)
setDT(dataset)[, Medias:=mean(Valor, na.rm=T), floor((Ano-3)/5)]

Выход:

      Ano Valor Medias
    <int> <num>  <num>
 1:  1988    15  19.50
 2:  1989    18  19.50
 3:  1990    20  19.50
 4:  1991    NA  19.50
 5:  1992    25  19.50
 6:  1993    27  30.50
 7:  1994    28  30.50
 8:  1995    NA  30.50
 9:  1996    32  30.50
10:  1997    35  30.50
11:  1998    36  40.20
12:  1999    38  40.20
13:  2000    40  40.20
14:  2001    42  40.20
15:  2002    45  40.20
16:  2003    46  50.75
17:  2004    NA  50.75
18:  2005    50  50.75
19:  2006    52  50.75
20:  2007    55  50.75
21:  2008    56  59.75
22:  2009    58  59.75
23:  2010    60  59.75
24:  2011    NA  59.75
25:  2012    65  59.75
26:  2013    66  70.20
27:  2014    68  70.20
28:  2015    70  70.20
29:  2016    72  70.20
30:  2017    75  70.20
31:  2018    76  78.00
32:  2019    78  78.00
33:  2020    80  78.00
      Ano Valor Medias
Ответ принят как подходящий

Вот dplyr версия:

library(dplyr)
n <- 5

dataset %>%
  arrange(Ano) %>%
  group_by(Group = floor((Ano - first(Ano))/n)) %>%
  mutate(Medias = mean(Valor, na.rm = TRUE)) %>%
  data.frame()

который возвращает следующее -

#    Ano Valor Group Medias
#1  1988    15     0  19.50
#2  1989    18     0  19.50
#3  1990    20     0  19.50
#4  1991    NA     0  19.50
#5  1992    25     0  19.50
#6  1993    27     1  30.50
#7  1994    28     1  30.50
#8  1995    NA     1  30.50
#9  1996    32     1  30.50
#10 1997    35     1  30.50
#11 1998    36     2  40.20
#12 1999    38     2  40.20
#13 2000    40     2  40.20
#14 2001    42     2  40.20
#15 2002    45     2  40.20
#16 2003    46     3  50.75
#17 2004    NA     3  50.75
#18 2005    50     3  50.75
#19 2006    52     3  50.75
#20 2007    55     3  50.75
#21 2008    56     4  59.75
#22 2009    58     4  59.75
#23 2010    60     4  59.75
#24 2011    NA     4  59.75
#25 2012    65     4  59.75
#26 2013    66     5  70.20
#27 2014    68     5  70.20
#28 2015    70     5  70.20
#29 2016    72     5  70.20
#30 2017    75     5  70.20
#31 2018    76     6  78.00
#32 2019    78     6  78.00
#33 2020    80     6  78.00

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

  1. У вас более 1 строки за год.
  2. У вас нет данных за все годы.

Тай, это именно то, что я хотел.

Pedro Cardoso 22.07.2024 15:49

@PedroCardoso Если вы ищете решение с использованием определенного пакета (в данном случае dplyr), лучше указать это и использовать соответствующий тег.

s_baldur 22.07.2024 15:50

Использование cut для создания группировки

library(dplyr)

dataset %>% 
  group_by(grp = cut(Ano, seq(min(Ano), max(Ano), 5), right=F)) %>% 
  mutate(medias = mean(Valor, na.rm=T)) %>% 
  ungroup() %>% 
  select(-grp)
# A tibble: 33 × 3
     Ano Valor medias
   <int> <dbl>  <dbl>
 1  1988    15   19.5
 2  1989    18   19.5
 3  1990    20   19.5
 4  1991    NA   19.5
 5  1992    25   19.5
 6  1993    27   30.5
 7  1994    28   30.5
 8  1995    NA   30.5
 9  1996    32   30.5
10  1997    35   30.5
# ℹ 23 more rows
# ℹ Use `print(n = ...)` to see more rows

Можешь попробовать

dataset %>%
    mutate(grp = ceiling(row_number() / 5)) %>%
    mutate(Medias = mean(Valor, na.rm = TRUE), .by = grp) %>%
    select(-grp)

который дает

    Ano Valor Medias
1  1988    15  19.50
2  1989    18  19.50
3  1990    20  19.50
4  1991    NA  19.50
5  1992    25  19.50
6  1993    27  30.50
7  1994    28  30.50
8  1995    NA  30.50
9  1996    32  30.50
10 1997    35  30.50
11 1998    36  40.20
12 1999    38  40.20
13 2000    40  40.20
14 2001    42  40.20
15 2002    45  40.20
16 2003    46  50.75
17 2004    NA  50.75
18 2005    50  50.75
19 2006    52  50.75
20 2007    55  50.75
21 2008    56  59.75
22 2009    58  59.75
23 2010    60  59.75
24 2011    NA  59.75
25 2012    65  59.75
26 2013    66  70.20
27 2014    68  70.20
28 2015    70  70.20
29 2016    72  70.20
30 2017    75  70.20
31 2018    76  78.00
32 2019    78  78.00
33 2020    80  78.00

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