Объединение перечисленных data.frames из data.frame - PullRequest
1 голос
/ 30 апреля 2020

Я запрашиваю данные из МВФ, используя пакет IMFData (https://github.com/mingjerli/IMFData).

Проблема в том, что я не знаю, как улучшить свой код. Есть 25 стран, которые я хотел бы получить данные. Я уверен, что мой код не самый лучший способ быстро создать нужный фрейм данных (в моем коде XDF).

library(IMFData)

databaseID <- "DOT"
startdate = "2013-01-01"
enddate = "2019-12-31"
checkquery = FALSE

queryfilter <- list(CL_FREQ = "M", CL_AREA_DOT = c("CA", "JP"), CL_INDICATOR_DOT = "TXG_FOB_USD", CL_COUNTERPART_AREA_DOT = "W00")
EXPORTS <- CompactDataMethod(databaseID, queryfilter, startdate, enddate, checkquery)

# I would like to improve this part:

XDF.1 <- EXPORTS$Obs[[1]]
XDF.2 <- EXPORTS$Obs[[2]]

XDF <- dplyr::left_join(XDF.1, XDF.2, by=c("@TIME_PERIOD"))

colnames(XDF) <- c("Date", "Canada", "Japan")

Ответы [ 2 ]

2 голосов
/ 30 апреля 2020

Вот базовый подход R, который даст вам все 227 областей с данными.

Сначала получите все области, доступные с помощью DataStructureMethod. Затем разбейте список на наборы из 25 областей, чтобы API не потерпел неудачу. Создайте новый пустой список для хранения возвращенных данных. Затем, используйте for l oop, чтобы выполнить итерацию по всем наборам областей и сохранить результаты в элемент списка.

library(IMFData)

databaseID <- "DOT"
startdate = "2013-01-01"
enddate = "2019-12-31"

areas <- DataStructureMethod("DOT")$CL_COUNTERPART_AREA_DOT$CodeValue
areas.list <- split(areas, ceiling(seq_along(areas)/25))

result.list <- list()
for(i in seq_along(areas.list)) {
  filter <- list(CL_FREQ = "M", CL_AREA_DOT = areas.list[[i]], CL_INDICATOR_DOT = "TXG_FOB_USD", CL_COUNTERPART_AREA_DOT = "W00")
  result.list[[i]] <- CompactDataMethod(databaseID, filter, startdate, enddate)
}

Теперь, когда у нас есть все данные, мы можем извлечь @OBS_VALUE из каждой области. Таким образом, мы можем не отставать от того, что есть, мы назначим имена столбцов для @REF_AREA. Тогда все, что нам нужно сделать, это связать все области вместе и добавить столбец периода времени.

result <- sapply(result.list,function(x){y <- sapply(x$Obs,function(y){y[['@OBS_VALUE']]}); colnames(y) <- x[["@REF_AREA"]]; y})
result <- do.call(cbind,result)
result <- cbind(timeperiod = result.list[[1]]$Obs[[1]][['@TIME_PERIOD']],result)
result[1:10,1:10]
      timeperiod BB          BM         AF          BS           AL           AW          BD            BZ          AO           
 [1,] "2013-01"  "28.609779" "2.763473" "37.545734" "140.793072" "182.268383" "15.248257" "2135.314764" "26.993657" "5738.361548"
 [2,] "2013-02"  "31.408923" "2.588724" "23.319418" "51.207085"  "160.256056" "13.357883" "1883.921679" "31.959256" "5093.785673"
 [3,] "2013-03"  "26.490062" "2.161194" "34.313418" "116.533489" "187.347118" "11.807801" "2074.639533" "36.975964" "5836.777823"
 [4,] "2013-04"  "30.969022" "6.541486" "27.46926"  "79.9772"    "199.063249" "15.363928" "1996.029477" "39.84747"  "4953.276187"
 [5,] "2013-05"  "27.633188" "3.030127" "32.675746" "765.5369"   "221.793898" "13.232063" "2247.850876" "73.201747" "5425.804703"
 [6,] "2013-06"  "24.064953" "2.816781" "29.454347" "60.756462"  "201.765833" "13.698186" "2291.680871" "32.821853" "5271.431577"
 [7,] "2013-07"  "26.25563"  "2.657042" "15.540238" "95.12846"   "233.746903" "14.499091" "2359.924118" "33.763333" "5666.628083"
 [8,] "2013-08"  "26.85187"  "2.883294" "21.369248" "74.317362"  "180.045606" "15.545374" "1985.100494" "31.342921" "5557.632778"
 [9,] "2013-09"  "25.025515" "3.368449" "26.061924" "89.380055"  "211.352443" "12.323627" "2441.630301" "25.107398" "5558.266666"
[10,] "2013-10"  "34.040048" "3.249082" "49.352241" "128.44329"  "227.724296" "17.172523" "2131.788729" "28.489788" "5411.943251"

Как вы, наверное, знаете, названия этих областей доступны в DataStructureMethod("DOT")$CL_COUNTERPART_AREA_DOT.

2 голосов
/ 30 апреля 2020

Возможно, вы захотите создать список и объединить его вместе с помощью функции Reduce (или purrr:::reduce). Я часто возвращаюсь к этому сообщению :

Предполагая, что у вас есть список X.DF данных с именем X_DF, вы можете сделать:

Reduce(function(dtf1, dtf2) merge(dtf1, dtf2, by = "i", all.x = TRUE),
        list_XDF)

или , если вы предпочитаете tidyverse синтаксис:

list_XDF %>% purrr::reduce(left_join, by=c("@TIME_PERIOD"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...