在 R 中重塑数据框
Reshaping a dataframe in R
我需要一些帮助来重新设计来自 R 包的函数的输出。
我的范围是以看起来与 output_imfr
的形状非常相似的方式重塑一个名为 output_IMFData
的数据框。 重现这些数据帧的 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
的"correspondence"不能丢失,即@REF-AREA
列中有国家名称代码和[=中的列18=] 有各自的时间序列数据。这是处理面板数据的非常麻烦的方式,因此我想将该数据框重塑为 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
}
}
我需要一些帮助来重新设计来自 R 包的函数的输出。
我的范围是以看起来与 output_imfr
的形状非常相似的方式重塑一个名为 output_IMFData
的数据框。 重现这些数据帧的 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
的"correspondence"不能丢失,即@REF-AREA
列中有国家名称代码和[=中的列18=] 有各自的时间序列数据。这是处理面板数据的非常麻烦的方式,因此我想将该数据框重塑为 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
}
}