在R中重塑一个数据帧
问题描述:
我需要一些帮助来重新设计R包中函数的输出。在R中重塑一个数据帧
我的范围是重塑一个名为output_IMFData
的数据框,其形状看起来与output_imfr
的形状非常相似。 一个MWE再现这些dataframes的代码是:
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
的形状转换成第二个“面板数据相关”数据框架的形状中,我的基本问题是我不知道如何处理output_IMFData
中的Obs
,这种方式不会失去与“对应”参考代码@REF-AREA
output_IMFData
也就是说,在列@REF-AREA
中有国名代码,Obs
中的列有它们各自的时间序列数据,这是使用面板数据非常麻烦的方式,因此我想将该数据帧重塑为output_imfr
数据帧的更好形式
答
感兴趣的数据存储在列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>
答
这里的另一种方法:
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
}
}
+1
这是非常直观和智能的答案,但一旦数据帧变大,它可能变得非常缓慢。 – msh855
对不起 - 我误解了您最初的代码,并认为它是从本地数据库中调用和/或需要大下载(我以前从未使用过'imfr'包)。看到编辑后的一些代码应该可以为你实际工作(请注意,'gather'将**不适用于这些数据) –
太棒了。如果有时间的话它会节省很多这就是我想知道的。 – msh855
Pererson,假设一个有点扭曲,而不是下载一个系列想下载两个。这种扭曲的MWE将是在'queryfilter'列表中将'CL_INDICATOR_IFS'重新定义为CL_INDICATOR_IFS = c(“IAD_BP6_USD”,“NGDP_EUR”)。换句话说,信件不仅应以@ REF-AREA为基础,而且还应以“@ INDICATOR”为指标。你能否建议你的代码应该如何修改? – msh855