【问题标题】:Reshaping a dataframe in R在 R 中重塑数据框
【发布时间】:2017-02-11 19:40:48
【问题描述】:

我需要一些帮助来重新设计通过 R 包提供的函数的输出。

我的范围是重塑一个名为output_IMFData 的数据框,使其看起来与output_imfr 的形状非常相似。 MWE 复制这些数据帧的代码是

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)

对于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)

output_IMFData 的输出如下所示:

但是,我想重新设计这个数据框,使其看起来像 output_imfr 的输出:

遗憾的是,我不是那种高级用户,也找不到可以帮助我的东西。我将output_IMFData 的形状转换为第二个“panel-data-looking”数据框架的形状的基本问题是我不知道如何以一种不会丢失的方式处理output_IMFData 中的Obs output_IMFData中与参考代码@REF-AREA的“对应关系”,即@REF-AREA列有国名代码,Obs列有各自的时间序列数据,这种方式很繁琐使用面板数据,因此我想将该数据框重塑为更好的output_imfr 数据框形式。

【问题讨论】:

    标签: r dataframe reshape2 data-cleaning panel-data


    【解决方案1】:

    感兴趣的数据存储在Obs 列中的列表中。这是一个dplyr 解决方案,用于拆分数据,打开列表,然后将它们重新拼接在一起。

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

    给予:

      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>
    

    【讨论】:

    • 很抱歉——我误解了您的初始代码,并认为它是从本地数据库调用和/或需要大量下载(我以前从未使用过 imfr 包)。请参阅编辑后的帖子,了解一些实际适用于您的代码(请注意,gather适用于这些数据)
    • 太好了。它节省了很多时间。这就是我想知道的。
    • Pererson,假设其中一个有点扭曲,而不是下载一个系列想要下载两个。这种扭曲的 MWE 将重新定义 queryfilter 列表中的 CL_INDICATOR_IFS' as CL_INDICATOR_IFS = c( "IAD_BP6_USD","NGDP_EUR")`。换句话说,对应关系不仅应基于@REF-AREA,还应基于指标,即@INDICATOR。你能建议你的代码应该如何修改吗?
    • 如果要保存其他列,请将它们添加到 lapply 内的 data.frame 的定义中,例如在iso2cx$Obs 之间添加indicator = x[["@INDICATOR"]]
    【解决方案2】:

    这是另一种方法:

    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
       }
    }
    

    【讨论】:

    • 这是一个非常直观和聪明的答案,但是一旦数据框变大,它可能会变得非常慢。
    猜你喜欢
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    相关资源
    最近更新 更多