在R中重塑数据帧

在R中重塑数据帧,r,dataframe,reshape2,data-cleaning,panel-data,R,Dataframe,Reshape2,Data Cleaning,Panel Data,我需要一些帮助来重新设计通过R包的函数的输出 我的工作范围是重塑名为output\u IMFData的数据帧,使其看起来与output\u imfr的形状非常相似再现这些数据帧的MWE代码为: library(imfr) output_imfr <- imf_data(database_id="IFS", indicator="IAD_BP6_USD", country = "", start = 2010, end = 2014, freq = "A", return_raw =FAL

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

我的工作范围是重塑名为
output\u IMFData
的数据帧,使其看起来与
output\u 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\u IMFData
的输出如下所示:

但是,我想重新设计这个数据帧,使其看起来像
output\u imfr
的输出:


可悲的是,我不是那么高级的用户,找不到可以帮助我的东西。在将
output\u IMFData
的形状转换为第二个“panel data looking”数据框架的形状时,我的基本问题是,我不知道如何处理
output\u IMFData
中的
Obs
,这样就不会丢失“对应关系”“使用
输出\u IMFData
中的参考代码
@REF-AREA
。也就是说,
@REF-AREA
列中有国家名称代码,
Obs
列中有各自的时间序列数据。这是一种非常麻烦的处理面板数据的方法,因此我想将该数据帧重新塑造为更好的
output\u imfr
dataframe形式。

感兴趣的数据存储在
Obs
列中的列表中。下面是一个
dplyr
解决方案,用于拆分数据,打开列表,然后将内容重新缝合在一起

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

head(longData)
longData%
拆分(1:nrow(%)%>%
lappy(函数(x){
数据帧(
iso2c=x[“@REF_AREA”]]
,x$Obs
)
}) %>%
绑定_行()
主管(长数据)
给出:

  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>
iso2c X.TIME\u PERIOD X.OBS\u VALUE X.OBS\u STATUS
1 FJ 2010 47.2107721901621
2 FJ 2011 48.28347
3 FJ 2012 51.08234999999
4 FJ 2013 157.015648875072
5 FJ 2014 186.623232882226
6 AW 2010 616.664804469274

还有另一种方法:

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

NewDataFrame很抱歉——我误解了您最初的代码,认为它是从本地数据库调用的和/或需要大量下载(我以前从未使用过
imfr
软件包)。请参阅编辑后的文章,了解一些实际适用于您的代码(请注意,
gather
不适用于这些数据),这非常好。这节省了很多时间。这就是我想知道的。Pererson,假设其中一个有点扭曲,与其下载一个系列,不如下载两个。对于这一转变,MWE将在
queryfilter
列表中将
CL\u INDICATOR\u IFS'重新定义为
CL\u INDICATOR\u IFS=c(“IAD\u BP6\u USD”,“NGDP\u EUR”)`。换句话说,对应关系不仅应基于@REF-AREA,还应基于指示器,即
@指示器
。您能建议如何修改您的代码吗?如果您想保存其他列,请将它们添加到
lappy
内的data.frame定义中,例如在
iso2c
x$Obs
之间添加
indicator=x[“@indicator”]]
。这是非常直观和明智的答案,然而,一旦数据帧变大,它会变得非常慢。
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
   }
}