简体   繁体   中英

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:

在此处输入图片说明

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

在此处输入图片说明

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.

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>

Here's another approach:

NewDataFrame <- data.frame(iso2c=character(), 
                 year=numeric(),
                 IAD_BP6_USD=character(), 
                 stringsAsFactors=FALSE)

newrow = 1

for(i in 1:nrow(output_IMFData)) { # for each row of your cludgy df
   for(j in 1:length(output_IMFData$Obs[[i]]$`@TIME_PERIOD`)) {  # for each year
     NewDataFrame[newrow,'iso2c']<-output_IMFData[i, '@REF_AREA']
     NewDataFrame[newrow,'year']<-output_IMFData$Obs[[i]]$`@TIME_PERIOD`[j]
     NewDataFrame[newrow,'IAD_BP6_USD']<-output_IMFData$Obs[[i]]$`@OBS_VALUE`[j]
     newrow<-newrow + 1 # increment down a row
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM