Search code examples
rdataframereshape2data-cleaningpanel-data

Reshaping a dataframe in R


I need some help to re-design the output of a function that comes through an R package.

My scope is to reshape a dataframe called output_IMFData in a way that look very similar to the shape of output_imfr. The codes of a MWE reproducing these dataframes are:

library(imfr)

output_imfr <- imf_data(database_id="IFS", indicator="IAD_BP6_USD", country = "", start = 2010, end = 2014, freq = "A", return_raw =FALSE, print_url = T, times = 3)

and for output_IMFData

library(IMFData)
databaseID  <- "IFS"
startdate   <- "2010"
enddate     <- "2014"
checkquery  <- FALSE
queryfilter  <- list(CL_FREA = "A", CL_AREA_IFS = "", CL_INDICATOR_IFS = "IAD_BP6_USD")
output_IMFData <- CompactDataMethod(databaseID, queryfilter, startdate, enddate, 
                                   checkquery)

the output from output_IMFData looks like this:

enter image description here

But, I want to redesign this dataframe to look like the output of output_imfr:

enter image description here

Sadly, I am not that advanced user and could not find something that can help me. My basic problem in converting the shape of output_IMFData to the shape of the second ``panel-data-looking" dataframework is that I don't know how to handle the Obs in output_IMFData in a way that cannot lose the "correspondence" with the reference code @REF-AREA in output_IMFData. That is, in column @REF-AREA there are codes of country names and the column in Obs has their respective time series data. This is very cumbersome way of working with panel data, and therefore I want to reshape that dataframe to the much nicer form of output_imfr dataframe.


Solution

  • The data of interest are stored in a list in the column Obs. Here is a dplyr solution to split the data, crack open the list, then stitch things back together.

    longData <-
      output_IMFData %>%
      split(1:nrow(.)) %>%
      lapply(function(x){
        data.frame(
          iso2c = x[["@REF_AREA"]]
          , x$Obs
        )
      }) %>%
      bind_rows()
    
    head(longData)
    

    gives:

      iso2c X.TIME_PERIOD      X.OBS_VALUE X.OBS_STATUS
    1    FJ          2010 47.2107721901621         <NA>
    2    FJ          2011         48.28347         <NA>
    3    FJ          2012 51.0823499999999         <NA>
    4    FJ          2013 157.015648875072         <NA>
    5    FJ          2014 186.623232882226         <NA>
    6    AW          2010 616.664804469274         <NA>