Расчет скользящего среднего за 5 лет в R с учетом обменных курсов с поправкой на инфляцию

Я пытался рассчитать 5-летнее скользящее среднее обменного курса в R, но не смог заставить код работать должным образом. Я хочу рассчитать скользящее среднее, аналогичное Коэффициенту пересчета Атласа, используемому Всемирным банком для оценок ВНД, с некоторыми небольшими изменениями.

Пример:

  • Для целевого 1965 года: прежде чем брать среднее/медианное значение, все обменные курсы (1961, 1962, 1963, 1964, 1965 годов) должны быть скорректированы с учетом инфляции, которая произошла между этими годами и 1965 годом.
  • Для целевого 1966 года: прежде чем брать среднее/медианное значение, все обменные курсы (1962, 1963, 1964, 1965, 1966 годы) должны быть скорректированы с учетом инфляции, которая произошла между этими годами и 1966 годом.
  • ... и так далее.
# Installing and loading required packages.
install.packages("WDI")
library(WDI)


# Getting GDP Deflator “NY.GDP.DEFL.ZS” and Exchange Rates “PA.NUS.ATLS”. 
WDI <- WDI(indicator=c("NY.GDP.DEFL.ZS","PA.NUS.ATLS"))

# Showing part of the Dataframe.
WDI |>

tibble()

                        country iso2c iso3c year NY.GDP.DEFL.ZS PA.NUS.ATLS
1                   Afghanistan    AF   AFG 1960             NA    45.00000
2                   Afghanistan    AF   AFG 1961             NA    45.00000
3                   Afghanistan    AF   AFG 1962             NA    45.00000
4                   Afghanistan    AF   AFG 1963             NA    45.00000
5                   Afghanistan    AF   AFG 1964             NA    45.00000
6                   Afghanistan    AF   AFG 1965             NA    45.00000
7                   Afghanistan    AF   AFG 1966             NA    45.00000
8                   Afghanistan    AF   AFG 1967             NA    45.00000
9                   Afghanistan    AF   AFG 1968             NA    45.00000
10                  Afghanistan    AF   AFG 1969             NA    45.00000
11                  Afghanistan    AF   AFG 1970             NA    45.00000
12                  Afghanistan    AF   AFG 1971             NA    45.00000
13                  Afghanistan    AF   AFG 1972             NA    45.00000
14                  Afghanistan    AF   AFG 1973             NA    45.00000
15                  Afghanistan    AF   AFG 1974             NA    45.00000


WDI |>

mutate (Atlas= median(PA.NUS.ATLS*(NY.GDP.DEFL.ZS/NY.GDP.DEFL.ZS/NY.GDP.DEFL.ZS[iso3c= = "USA"]/NY.GDP.DEFL.ZS[iso3c= = "USA"]),
                      
lag(PA.NUS.ATLS,n=1)*(NY.GDP.DEFL.ZS/lag(NY.GDP.DEFL.ZS,n=1)/NY.GDP.DEFL.ZS[iso3c= = "USA"]/lag(NY.GDP.DEFL.ZS[iso3c= = "USA"],n=1)), 

lag(PA.NUS.ATLS,n=2)*(NY.GDP.DEFL.ZS/lag(NY.GDP.DEFL.ZS,n=2)/NY.GDP.DEFL.ZS[iso3c= = "USA"]/lag(NY.GDP.DEFL.ZS[iso3c= = "USA"],n=2)), 

lag(PA.NUS.ATLS,n=3)*(NY.GDP.DEFL.ZS/lag(NY.GDP.DEFL.ZS,n=3)/NY.GDP.DEFL.ZS[iso3c= = "USA"]/lag(NY.GDP.DEFL.ZS[iso3c= = "USA"],n=3)), 

lag(PA.NUS.ATLS,n=4)*(NY.GDP.DEFL.ZS/lag(NY.GDP.DEFL.ZS,n=4)/NY.GDP.DEFL.ZS[iso3c= = "USA"]/lag(NY.GDP.DEFL.ZS[iso3c= = "USA"],n=4)) ,

lag(PA.NUS.ATLS,n=5)*(NY.GDP.DEFL.ZS/lag(NY.GDP.DEFL.ZS,n=5)/NY.GDP.DEFL.ZS[iso3c= = "USA"]/lag(NY.GDP.DEFL.ZS[iso3c= = "USA"],n=5)),na.rm=FALSE), by= c("country","year"))

Код выше приводит к этой ошибке:

Error in `mutate()`:
ℹ In argument: `by = c("country", "year")`.
Caused by error:
! `by` must be size 17024 or 1, not 2.
Run `rlang::last_trace()` to see where the error occurred.

Вы уверены, что не хотите summarise вместо mutate?

Edward 12.07.2024 09:30

@Эдвард Нет, я хочу создать новый столбец в фрейме данных, состоящий из значений обменного курса Атласа.

Anon9001 12.07.2024 09:34

@Edward Интересно, теперь код работает, но столбец Атласа полон значений NA для всех стран, кроме США, и в этом случае он дает неправильные значения.

Anon9001 12.07.2024 09:44

@Edward Да, это моя вина, поскольку я не очень хорошо разбираюсь в программировании на R, но я уже правильно выполнил эти расчеты в электронной таблице Excel, и мне интересно, что именно я делаю неправильно в R. Вот ссылка на таблицу: архив. org/download/ACFExample/ACFExample.xlsx

Anon9001 12.07.2024 09:51

Ваш R-код выглядит неправильно. Не хватает скобок.

Edward 12.07.2024 10:04

@Эдвард, я думаю, ты имел в виду, что мне следовало заключить эту строку в скобки: NY.GDP.DEFL.ZS[iso3c= = "USA"]/lag(NY.GDP.DEFL.ZS[iso3c= = "USA"‌​ ],n=1) .После этого значения Атласа верны для США, но по-прежнему недействительны для других стран.

Anon9001 12.07.2024 10:32

@Эдвард, думаю, я знаю, в чем проблема. Взятие простого среднего обменного курса за 5 лет с использованием функции «лаг» дает мне то же значение, что и обменный курс. Должно быть, я делаю что-то не так с функцией задержки. WDI |> mutate (Атлас= медиана(PA.NUS.ATLS,lag(PA.NUS.ATLS,n=1),lag(PA.NUS.ATLS,n=2)‌​,lag(PA.NUS.ATLS ,n=3‌), lag(PA.NUS.ATLS,n=4) ,lag(PA.NUS.ATLS,n=5),na.rm=TRUE), .by= c("country"," год")) |> filter(!is.na(Атлас)) |> tibble()

Anon9001 12.07.2024 11:14

Этот вопрос похож на: Вычисление скользящего среднего. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.

Zé Loff 12.07.2024 12:03

@zé-loff Это немного сложнее, чем просто вычисление скользящего среднего с использованием Rollmean. Для целевого 1965 года, прежде чем брать среднее значение/медиану, все обменные курсы (1961, 1962, 1963, 1964, 1965 годы) должны быть скорректированы с учетом инфляции, которая произошла между этими годами и 1965 годом. Для целевого 1966 года, прежде чем брать Среднее/медианное значение всех обменных курсов (1962, 1963, 1964, 1965, 1966 годов) должно быть скорректировано с учетом инфляции, которая произошла между этими годами и 1966 годом. И так далее. Я пытался использовать функцию задержки из dplyr, чтобы это работало, но она просто дает мне значения NA.

Anon9001 12.07.2024 12:12

@ZéLoff: это не дубликат, он другой, потому что он также хочет рассчитать обменные курсы с поправкой на инфляцию. Я отредактировал это в заголовок. (Anon9001: это полезно для объяснения того, что сложно и почему это не следует закрывать как обман.)

smci 12.07.2024 13:15

Я откатил ваше редактирование. Если вам удалось решить свою проблему, это здорово, но вопрос следует сохранить как вопрос с исходной проблемой, а не превращать в решение, поскольку именно для этого и нужны ответы.

Mark Rotteveel 14.07.2024 11:20
Стоит ли изучать 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
11
106
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У вас есть by вместо .by. В противном случае mutate подумает, что вам нужен еще один столбец с именем «by», длина которого равна 2 и не равна длине результирующего тиббла. (в отличие от data.frames, для тибблов действуют более строгие правила, разрешающие переработку).

После того, как в комментариях была предоставлена ​​дополнительная информация (ссылка на файл Excel с правильной формулой), было обнаружено еще несколько проблем.


  • Вам нужно поместить значения США в другой столбец, выровняв их по годам.
  • Не группируйте по годам, так как вам нужны лаги,
  • Сначала нам нужно вычислить лаги, затем медианы по строкам,
  • У вас не хватает скобок.

inner_join(WDI, 
           filter(WDI, iso3c= = "USA") |>
             rename(NY.GDP.DEFL.ZS.USA=NY.GDP.DEFL.ZS) |>
             select(year, NY.GDP.DEFL.ZS.USA), by='year') |>
  mutate(a2=lag(PA.NUS.ATLS,n=4)*(NY.GDP.DEFL.ZS/lag(NY.GDP.DEFL.ZS,n=4)/(NY.GDP.DEFL.ZS.USA/lag(NY.GDP.DEFL.ZS.USA,n=4))),
         a3=lag(PA.NUS.ATLS,n=3)*(NY.GDP.DEFL.ZS/lag(NY.GDP.DEFL.ZS,n=3)/(NY.GDP.DEFL.ZS.USA/lag(NY.GDP.DEFL.ZS.USA,n=3))),
         a4=lag(PA.NUS.ATLS,n=2)*(NY.GDP.DEFL.ZS/lag(NY.GDP.DEFL.ZS,n=2)/(NY.GDP.DEFL.ZS.USA/lag(NY.GDP.DEFL.ZS.USA,n=2))),
         a5=lag(PA.NUS.ATLS,n=1)*(NY.GDP.DEFL.ZS/lag(NY.GDP.DEFL.ZS,n=1)/(NY.GDP.DEFL.ZS.USA/lag(NY.GDP.DEFL.ZS.USA,n=1))),
         a6=    PA.NUS.ATLS     *(NY.GDP.DEFL.ZS/    NY.GDP.DEFL.ZS     /(NY.GDP.DEFL.ZS.USA/    NY.GDP.DEFL.ZS.USA)), .by = "iso3c") |>
  rowwise() |>
  mutate(Atlas=median(c_across(a2:a6), na.rm=FALSE)) |>
  select(-c(a2:a6, NY.GDP.DEFL.ZS.USA)) |>
  filter(!is.na(Atlas))

# A tibble: 10,179 × 7
# Rowwise: 
   country     iso2c iso3c  year NY.GDP.DEFL.ZS PA.NUS.ATLS Atlas
   <chr>       <chr> <chr> <int>          <dbl>       <dbl> <dbl>
 1 Afghanistan AF    AFG    2004           46.5        47.8  53.1
 2 Afghanistan AF    AFG    2005           51.5        49.7  57.1
 3 Afghanistan AF    AFG    2006           55.2        49.9  53.5
 4 Afghanistan AF    AFG    2007           67.7        49.8  61.6
 5 Afghanistan AF    AFG    2008           69.1        50.9  59.7
 6 Afghanistan AF    AFG    2009           67.6        49.3  49.5
 7 Afghanistan AF    AFG    2010           70.2        45.8  50.5
 8 Afghanistan AF    AFG    2011           81.8        47.8  56.8
 9 Afghanistan AF    AFG    2012           87.8        51.7  55.1
10 Afghanistan AF    AFG    2013           92.0        56.5  56.5
# ℹ 10,169 more rows
# ℹ Use `print(n = ...)` to see more rows

@ Anon9001 Обновлено. Пожалуйста, проверьте... это оказалось сложнее, чем я думал сначала..

Edward 13.07.2024 00:22

Извините за поздний ответ, я спал, когда вы обновили пост. Я быстро проверил код, и вывод кажется правильным. Большое спасибо, Эдвард, за вашу ценную помощь и время. Я одобрил ваш ответ.

Anon9001 13.07.2024 12:50

Я хотел проголосовать за ваш ответ, но у меня низкая репутация. Извини.

Anon9001 13.07.2024 12:58

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