Как преобразовать противоречивые годовые данные в пятилетние средние? - PullRequest
1 голос
/ 09 апреля 2020

Я новичок в R и пытаюсь преобразовать мой годовой несоответствующий набор данных (набор данных не обязательно содержит данные за каждый год, но содержат некоторые переменные) в пятилетние средние. Я пытаюсь построить для l oop (хотя любой метод рекомендуется), чтобы сгенерировать новую переменную для среднего числа известных лет, но создание условий по годам оказалось трудным. Другими словами, если набор данных содержит значение для всех пяти лет, он сгенерирует среднее из пяти (та же идея, если у него есть данные за 4-2 года), и если у него есть данные только для одного, он примет значение один год, в то же время создавая новую переменную для времени, которая равна наименьшему / наибольшему из лет.

Я пытался показать это, используя смоделированные данные (это моделируется для среднего значения за 3 года, но я надеюсь, что тот же метод применяется для 5)

Это смоделированные данные, которые у меня есть на данный момент, переменная, указывающая годы, данные и код страны.

df <- read.table(
text =
"Year, Data,Country
1,2,US
3,2,US
6,5,US
7,1,US
8,5,US
1,3,UK
2,5,UK
3,4,UK
4,3,UK
9,2,UK
", sep = ",", header = TRUE)
df

Это смоделированные данные того, чего я хотел бы достичь. Данные сортируются по среднему значению за 3 года, и создается новая переменная с указанием года, которая принимает значение «самого низкого» года. (Я сделал это среднее 3 и включил среднее вычисление для упрощения)

df2 <- read.table(
text =
"Year, Data,Country,YearAvg,Average
1,2,US,1,4/2=2
3,2,US,4,5/1=5
6,5,US,7,3
7,1,US,NA,NA
8,5,US,NA,NA
1,3,UK,1,12/3=4
2,5,UK,4,3
3,4,UK,7,2
4,3,UK,NA,NA
9,2,UK,NA,NA
", sep = ",", header = TRUE)
df2

Любое предложение, как это можно кодировать в R?

Редактировать:

df <- read.table(
text =
"year, Data,country
1,2,US
3,2,US
4,5,US
5,1,US
6,3,US
7,5,US
8,4,US
9,3,US
10,4,US
11,9,US
", sep = ",", header = TRUE)
df

df2 = setkey(setDT(df), year, country)[CJ(year = seq(min(year), max(year)), country = unique(country))
                                 ][ , avg := frollmean(Data, 5, align = "left", na.rm = TRUE), by = country
                                    ][order(country, year)
                                      ][(rowid(country) %% 5) == 1]
df2

1 Ответ

1 голос
/ 09 апреля 2020

Вот вариант data.table.

  • Сначала будут расширены строки, чтобы заполнить пропущенные годы для каждой страны (таким образом, у вас будет год 1, 2, 3 и т. Д. c. Даже если нет данных)
  • Тогда вы frollmean получите скользящее среднее и проигнорируете NA в Data (выровняйте влево по среднему значению за n лет)
  • Вы можете выбрать каждые 3 лет с (rowid(Country) %% 3) == 1 (и меняйте 3 на 5, чтобы получать каждые 5 лет)

Дайте мне знать, если это работает для ваших целей.

library(data.table)

setkey(setDT(df), Year, Country)[CJ(Year = seq(min(Year), max(Year)), Country = unique(Country))
                                 ][ , avg := frollmean(Data, 3, align = "left", na.rm = TRUE), by = Country
                                    ][order(Country, Year)
                                      ][(rowid(Country) %% 3) == 1]

Вывод

   Year Data Country avg
1:    1    3      UK   4
2:    4    3      UK   3
3:    7   NA      UK   2
4:    1    2      US   2
5:    4   NA      US   5
6:    7    1      US   3
...