Я пытался рассчитать 5-летнее скользящее среднее обменного курса в R, но не смог заставить код работать должным образом. Я хочу рассчитать скользящее среднее, аналогичное Коэффициенту пересчета Атласа, используемому Всемирным банком для оценок ВНД, с некоторыми небольшими изменениями.
Пример:
# 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.
@Эдвард Нет, я хочу создать новый столбец в фрейме данных, состоящий из значений обменного курса Атласа.
@Edward Интересно, теперь код работает, но столбец Атласа полон значений NA для всех стран, кроме США, и в этом случае он дает неправильные значения.
@Edward Да, это моя вина, поскольку я не очень хорошо разбираюсь в программировании на R, но я уже правильно выполнил эти расчеты в электронной таблице Excel, и мне интересно, что именно я делаю неправильно в R. Вот ссылка на таблицу: архив. org/download/ACFExample/ACFExample.xlsx
Ваш R-код выглядит неправильно. Не хватает скобок.
@Эдвард, я думаю, ты имел в виду, что мне следовало заключить эту строку в скобки: NY.GDP.DEFL.ZS[iso3c= = "USA"]/lag(NY.GDP.DEFL.ZS[iso3c= = "USA" ],n=1) .После этого значения Атласа верны для США, но по-прежнему недействительны для других стран.
@Эдвард, думаю, я знаю, в чем проблема. Взятие простого среднего обменного курса за 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()
Этот вопрос похож на: Вычисление скользящего среднего. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.
@zé-loff Это немного сложнее, чем просто вычисление скользящего среднего с использованием Rollmean. Для целевого 1965 года, прежде чем брать среднее значение/медиану, все обменные курсы (1961, 1962, 1963, 1964, 1965 годы) должны быть скорректированы с учетом инфляции, которая произошла между этими годами и 1965 годом. Для целевого 1966 года, прежде чем брать Среднее/медианное значение всех обменных курсов (1962, 1963, 1964, 1965, 1966 годов) должно быть скорректировано с учетом инфляции, которая произошла между этими годами и 1966 годом. И так далее. Я пытался использовать функцию задержки из dplyr, чтобы это работало, но она просто дает мне значения NA.
@ZéLoff: это не дубликат, он другой, потому что он также хочет рассчитать обменные курсы с поправкой на инфляцию. Я отредактировал это в заголовок. (Anon9001: это полезно для объяснения того, что сложно и почему это не следует закрывать как обман.)
Я откатил ваше редактирование. Если вам удалось решить свою проблему, это здорово, но вопрос следует сохранить как вопрос с исходной проблемой, а не превращать в решение, поскольку именно для этого и нужны ответы.
У вас есть 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 Обновлено. Пожалуйста, проверьте... это оказалось сложнее, чем я думал сначала..
Извините за поздний ответ, я спал, когда вы обновили пост. Я быстро проверил код, и вывод кажется правильным. Большое спасибо, Эдвард, за вашу ценную помощь и время. Я одобрил ваш ответ.
Я хотел проголосовать за ваш ответ, но у меня низкая репутация. Извини.
Вы уверены, что не хотите
summarise
вместоmutate
?