
<!-- README.md is generated from README.Rmd. Please edit that file -->

# fedstatAPIr

<!-- badges: start -->
<!-- badges: end -->

fedstatAPIr представляет собой неофициальное API для загрузки данных с
fedstat.ru (система ЕМИСС Росстата) с заданными фильтрами.

Пакет позволяет сэкономить ⏳ и нервы 😡 при работе с бесконечно
падающим ЕМИСС через автоматическое повторение неотвеченных запросов и
сохранение ранее использованных настроек фильтров.

## Поделитесь чеканной монетой :)

Проект уже существует длительное время и, по-видимому, получился
довольно стабильным ⚖️ и легковесным 🪽. Если пакет оказал влияние на
Вашу деятельность, просим оказать
[поддержку](https://pay.cloudtips.ru/p/db468def). Если будет набрана
необходимая сумма, также сделаем порт на Python и API для витрины данных
Росстата (showdata). Спасибо за использование пакета!

## Установка

На данный момент пакет доступен только на R, Вы можете загрузить
fedstatAPIr из [CRAN](https://CRAN.R-project.org), используя следующую
команду в R:

``` r
install.packages("fedstatAPIr")
```

Версия для разработки может быть загружена следующей командой:

``` r
# install.packages("devtools")
devtools::install_github("DenchPokepon/fedstatAPIr")
```

## Использование

Загрузим данные по инфляции к предыдущему месяцу и к соотв. месяцу
прошлого года за январь 2023 года по всем товарам и услугам только по
России

Возьмем номер индикатора из URL веб страницы с данными
<https://fedstat.ru/indicator/31074>

``` r
library(fedstatAPIr)
data <- fedstat_data_load_with_filters(
  indicator_id = "31074",
  filters = list(
    "Классификатор объектов административно-территориального деления (ОКАТО)" = "Приморский край",
    "Виды показателя" = c(
      "К соответствующему периоду предыдущего года",
      "К предыдущему месяцу"
    ),
    "Период" = "Январь",
    "Год" = "2023",
    "Виды товаров и услуг" = "*"
  )
)
```

| EI      | ObsValue | PERIOD | Time | s_POK                                       | s_grtov                            | s_OKATO         | s_OKATO_code | s_POK_code | s_grtov_code |
|:--------|---------:|:-------|:-----|:--------------------------------------------|:-----------------------------------|:----------------|:-------------|:-----------|:-------------|
| процент |   100.83 | январь | 2023 | К предыдущему месяцу                        | Все товары и услуги                | Приморский край | 05000000000  | 44         | 1            |
| процент |   111.25 | январь | 2023 | К соответствующему периоду предыдущего года | Все товары и услуги                | Приморский край | 05000000000  | 9          | 1            |
| процент |   100.61 | январь | 2023 | К предыдущему месяцу                        | Все товары                         | Приморский край | 05000000000  | 44         | 2            |
| процент |   111.13 | январь | 2023 | К соответствующему периоду предыдущего года | Все товары                         | Приморский край | 05000000000  | 9          | 2            |
| процент |   100.78 | январь | 2023 | К предыдущему месяцу                        | Базовый индекс потребительских цен | Приморский край | 05000000000  | 44         | 3            |
| процент |   113.62 | январь | 2023 | К соответствующему периоду предыдущего года | Базовый индекс потребительских цен | Приморский край | 05000000000  | 9          | 3            |

Необходимо учитывать, что ЕМИСС часто находится под большой нагрузкой,
поэтому не стоит загружать больше 500 тысяч строк за один запрос. В
случае большой выгрузки желательно разбить запросы на подзапросы, в ином
случае ЕМИСС может игнорировать такие большие запросы.

## Спецификация фильтров

Фильтры задаются в виде именованного R списка (list):

``` r
filters = list(
  "Название поля фильтра 1" = c("Значение 1", "Значение 2"),
  "Название поля фильтра 2" = "Значение 1",
  "Название поля фильтра 3" = "*"  # все значения
)
```

Где `"Название поля фильтра"` может быть, например `"Год"`, а значение
для этого поля `"2023"`.

Поля и значения фильтров берутся прямо из названий фильтров на
fedstat.ru, в `filters` они должны быть такими же. Однако разные
регистры фильтров и лишние пробелы не сломают фильтрацию.

Доступны следующие специальные значения фильтров:

1.  Звездочка (`"*"`) выбирает все данные по этому полю фильтра.

**Важно:** все фильтры с несколькими возможными значениями должны быть
явно указаны. Если фильтр не указан, будет возвращена ошибка с
перечислением неуказанных полей. Используйте `"*"` для явного выбора
всех значений. Это важно контролировать ответственно, так как Вы можете
случайно сделать запрос на всю базу данных. Безответственная настройка
фильтров приведет к замедлению работы сервиса для всех пользователей
fedstat.ru.

## Доступные индикаторы

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

Внутри пакета доступна база данных всех индикаторов, по которым
представлены данные на fedstat.ru. Она содержится в переменной
`fedstat_indicators_names_database`.

Все доступные фильтры каждого индикатора можно посмотреть через вызов
функции

``` r
data_ids <- fedstat_get_data_ids("31074")
```

Результат выглядит следующим образом

| filter_field_id | filter_field_title | filter_value_id | filter_value_title                             | filter_field_object_ids |
|:----------------|:-------------------|:----------------|:-----------------------------------------------|:------------------------|
| 0               | Показатель         | 31074           | Индексы потребительских цен на товары и услуги | filterObjectIds         |
| 3               | Год                | 2002            | 2002                                           | columnObjectIds         |
| 3               | Год                | 2003            | 2003                                           | columnObjectIds         |
| 3               | Год                | 2004            | 2004                                           | columnObjectIds         |
| 3               | Год                | 2005            | 2005                                           | columnObjectIds         |
| 3               | Год                | 2006            | 2006                                           | columnObjectIds         |

Также можно посмотреть полный внутренний словарь (соотношения кодов и
человеческих названий сущностей) через задание аргумента
`return_type = "dictionary"`

``` r
data_dict <- fedstat_data_load_with_filters(
  indicator_id = "31074",
  filters = list(
    # Здесь фильтры не важны, но нужно поставить валидную комбинацию, которая отдаст хотя бы одну строчку данных
    "Классификатор объектов административно-территориального деления (ОКАТО)" = "Приморский край",
    "Виды показателя" = c(
      "К соответствующему периоду предыдущего года",
      "К предыдущему месяцу"
    ),
    "Период" = "Январь",
    "Год" = "2023",
    "Виды товаров и услуг" = "*"
  ),
  return_type = "dictionary"
)
```

| field_id | field_title     | value_id | value_title                                  |
|:---------|:----------------|:---------|:---------------------------------------------|
| s_POK    | Виды показателя | 4        | К декабрю предыдущего года                   |
| s_POK    | Виды показателя | 29       | К предыдущему кварталу                       |
| s_POK    | Виды показателя | 44       | К предыдущему месяцу                         |
| s_POK    | Виды показателя | 30       | К соответствующему кварталу предыдущего года |
| s_POK    | Виды показателя | 9        | К соответствующему периоду предыдущего года  |
| s_POK    | Виды показателя | 41       | Квартал к отчетному году                     |

## Продвинутое использование

Функция `fedstat_data_load_with_filters` является оберткой из отдельных
функций, которые отвечают за:

1.  Загрузку id фильтров и CSRF-токена через GET запрос
    (`fedstat_get_data_ids`);
2.  Фильтрацию данных на основе `filters` с учетом специальных значений
    (`fedstat_data_ids_filter`);
3.  Отправку POST запроса с телом из фильтров
    (`fedstat_post_data_ids_filtered`);
4.  Парсинг полученного SDMX файла в таблицу
    (`fedstat_parse_sdmx_to_table`).

По каждой функции доступна подробная документация, которую можно вызвать
в R через функцию `help()`. Например
`help("fedstat_data_load_with_filters")` или
`?fedstat_data_load_with_filters`.

Загрузим данные, используя каждую функцию отдельно:

``` r
# CSRF-токен автоматически извлекается и передаётся через атрибуты data_ids.
# Токен одноразовый — каждый POST потребляет токен.
data_ids <- fedstat_get_data_ids("31074")

data_ids_filtered <- data_ids %>%
  fedstat_data_ids_filter(
    filters = list(
      "Классификатор объектов административно-территориального деления (ОКАТО)" = "Приморский край",
      "Виды показателя" = c(
        "К соответствующему периоду предыдущего года",
        "К предыдущему месяцу"
      ),
      "Период" = "Январь",
      "Год" = "2023",
      "Виды товаров и услуг" = "*"
    )
  )

data_sdmx_parsed <- data_ids_filtered %>%
  fedstat_post_data_ids_filtered(data_format = "sdmx") %>%
  fedstat_parse_sdmx_to_table()

# Для повторной загрузки или загрузки в другом формате нужен новый токен:
data_ids_for_excel <- fedstat_get_data_ids("31074") %>%
  fedstat_data_ids_filter(
    filters = list(
      "Классификатор объектов административно-территориального деления (ОКАТО)" = "Приморский край",
      "Виды показателя" = c(
        "К соответствующему периоду предыдущего года",
        "К предыдущему месяцу"
      ),
      "Период" = "Январь",
      "Год" = "2023",
      "Виды товаров и услуг" = "*"
    )
  )

# Также можем загружать excel
data_xls_binary <- data_ids_for_excel %>%
  fedstat_post_data_ids_filtered(data_format = "excel")

# Также можем записать в xls файл.
writeBin(data_xls_binary, "data.xls")
# Его формат зависит от колонки filter_field_object_ids в data_ids, можно изменять самостоятельно
```

## Устранение проблем

### Ошибка 403 (Forbidden)

ЕМИСС может блокировать запросы с нестандартными заголовками. Пакет
устанавливает заголовки по умолчанию, но если блокировка всё ещё
происходит, можно вручную задать свои:

``` r
httr::set_config(httr::add_headers(
  'User-Agent' = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
  'Accept' = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
  'Accept-Language' = "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
  'Connection' = "keep-alive"
))
```

Вызовите эту команду **один раз** перед использованием функций пакета.

### Ошибка 503 (Service Unavailable)

ЕМИСС перегружен. Рекомендации:

-   Уменьшите объём запроса через фильтры
-   Повторите запрос позже
-   Разбейте большие запросы на несколько мелких

### Ошибка 302 (Redirect)

Сервер отклонил запрос. Возможные причины:

-   Комбинация фильтров не возвращает данных
-   Некорректные значения фильтров
-   Запрос слишком широкий или слишком узкий

Проверьте доступные значения фильтров через `fedstat_get_data_ids()`.

### “CSRF token validation failed”

CSRF-токен одноразовый. При использовании отдельных функций (не обёртки)
нужно заново вызвать `fedstat_get_data_ids()` для каждого POST:

``` r
data_ids <- fedstat_get_data_ids("31074")  # <- свежий токен
data <- data_ids %>%
  fedstat_data_ids_filter(filters = ...) %>%
  fedstat_post_data_ids_filtered() %>%
  fedstat_parse_sdmx_to_table()
```

Функция-обёртка `fedstat_data_load_with_filters()` делает это
автоматически при повторных попытках.

### “No data found” / HTML вместо данных

Обновите пакет до версии \>= 1.1.0. Старая версия обращается к
устаревшему эндпойнту, который больше не отдаёт данные.

## Помощь

Вопросы можно писать на почту <deniskrylovvit@gmail.com>

------------------------------------------------------------------------

## Разработка

Буду рад Вашему вкладу в проект. Перед коммитом изменений необходимо
пройти R CRAN check –as-cran.
