在R中重塑数据帧
我需要一些帮助来重新设计通过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
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
}
}