2016-10-03 130 views
-1

我需要一些幫助來重新設計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輸出看起來是這樣的:

enter image description here

但是,我想重新設計這個數據幀看起來像output_imfr的輸出:

enter image description here

可悲的是,我沒有那麼高級的用戶,但沒有找到的東西,可以幫助我。在將output_IMFData的形狀轉換成第二個「面板數據相關」數據框架的形狀中,我的基本問題是我不知道如何處理output_IMFData中的Obs,這種方式不會失去與「對應」參考代碼@REF-AREAoutput_IMFData也就是說,在列@REF-AREA中有國名代碼,Obs中的列有它們各自的時間序列數據,這是使用面板數據非常麻煩的方式,因此我想將該數據幀重塑爲output_imfr數據幀的更好形式

回答

2

感興趣的數據存儲在列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> 
+0

對不起 - 我誤解了您最初的代碼,並認爲它是從本地數據庫中調用和/或需要大下載(我以前從未使用過'imfr'包)。看到編輯後的一些代碼應該可以爲你實際工作(請注意,'gather'將**不適用於這些數據) –

+0

太棒了。如果有時間的話它會節省很多這就是我想知道的。 – msh855

+0

Pererson,假設一個有點扭曲,而不是下載一個系列想下載兩個。這種扭曲的MWE將是在'queryfilter'列表中將'CL_INDICATOR_IFS'重新定義爲CL_INDICATOR_IFS = c(「IAD_BP6_USD」,「NGDP_EUR」)。換句話說,信件不僅應以@ REF-AREA爲基礎,而且還應以「@ INDICATOR」爲指標。你能否建議你的代碼應該如何修改? – msh855

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

這是非常直觀和智能的答案,但一旦數據幀變大,它可能變得非常緩慢。 – msh855