2016-05-31 56 views
-2

數據非常格式化,但我無法對源執行任何操作。我試圖以更好的方式對它進行排序/格式化,以便對數據進行分析。排序具有多個日期列的數據框

在我的數據集中有多個以不同開始日期開始的日期列。這裏有一個例子:

DF <- data.frame(V1 = c('FS', 'Date', '1/31/2000','2/29/2000','',''), 
       V1.1 = c('','','99.87','99.97','',''), 
       V10 = c('FIIB','Date','10/29/2004','10/30/2004','12/31/2004','1/31/2005'), 
       V10.1 = c('','','103.24','104.82','105.14','107.68')) 

它看起來像以下,但有數百列:

  V1 V1.1  V10 V10.1 
1  FS    FIIB  
2  Date    Date  
3 1/31/2000 99.87 10/29/2004 103.24 
4 2/29/2000 99.97 11/30/2004 104.82 
5     12/31/2004 105.14 
6     1/31/2005 107.68 

的開始日期是固定的,這是2000年1月31日,而結束日期爲上個月底,這是2016年4月30日。結束日期將逐月更新。如果證券在某些月份沒有回報,則使用空白或NA。例如,由於FS只有1/31和2/29/2000的價格,其餘的(從2000年3月31日到2016年4月30日)將是空白或NAs。有了這樣說,數據應該是這樣的:

V1   V2  V3  V4 
Date  FS  FIIB ...  
1/31/2000 99.87 NA  ... 
2/29/2000 99.97 NA  ... 
...  ... ... ... 
10/29/2004 NA  103.24 ... 
11/30/2004 NA  104.82 ... 
12/31/2004 NA  105.14 ... 
1/31/2005 NA  107.68 ... 
...  ... ... ... 
4/30/2016 ... ... ... 

我知道如何使用order基於特定列對數據進行排序。但有了多個日期,我需要一些幫助。謝謝!

+0

是'FS','FIIB'和'日期'值應該是變量名?您的示例和期望輸出之間的移動邏輯是什麼? – effel

+0

你究竟想做什麼? 「清理和整理我的數據集」很模糊...... – nsheff

+0

是的,'FS'和'FIIB'是變量(安全)名稱。正如您所看到的,每個證券在下一列中都有下面的每月日期和每月的價格。問題是證券之間的開始日期不同。例如,'FS'具有1/31和2/29/2000的價格數據,而'FIIB'具有從10/29/2004到2016/4/30的數據。我想創建一個「日期」列,並相應地適合每月的數據。 –

回答

2

可以按如下步驟清理這個漂亮的格式錯誤數據集:

# convert the columns to character values 
# this is only needed if they are stored as factor variables 
# alternatively you can read the dataframe with 'stringsAsFactors = FALSE' 
DF[] <- lapply(DF, as.character) 
# replace the empty spots with NA's 
DF[DF==''] <- NA 

# extract the first two columns into a new dataframe 
DF1 <- DF[complete.cases(DF[,1:2]), 1:2] 
# assign the correct names 
names(DF1) <- c(DF[2,1],DF[1,1]) 

# extract the next two columns into a new dataframe 
DF2 <- DF[complete.cases(DF[,3:4]), 3:4] 
# assign the correct names 
names(DF2) <- c(DF[2,3],DF[1,3]) 

# merge them into a new dataframe 
DFnew <- merge(DF1, DF2, by = 'Date', all = TRUE) 

這給:

> DFnew 
     Date FS FIIB 
1 1/31/2000 99.87 <NA> 
2 2/29/2000 99.97 <NA> 
3 10/29/2004 <NA> 103.24 
4 10/30/2004 <NA> 104.82 
5 12/31/2004 <NA> 105.14 
6 1/31/2005 <NA> 107.68 

當你有很多列在原來的組織以同樣的方式數據框,輸入所有組合非常麻煩。對於這種情況下可以處理該格式錯誤的數據幀如下(轉換爲字符值,並更換空斑的保持相同):

# split the badly formatted dataframe into a list of dataframes 
lst1 <- lapply(seq(2,ncol(DF),2), function(i) DF[complete.cases(DF[,(i-1):i]), (i-1):i]) 

# set the names for each dataframe in the list 
lst2 <- lapply(seq(lst1), function(x) {names(lst1[[x]]) <- c(DF[2,(x*2-1)],DF[1,(x*2-1)]); return(lst1[[x]])}) 

# merge the list of dataframes back into one new dataframe 
DFnew <- Reduce(function(...) merge(..., by = 'Date', all = TRUE), lst2) 

其給出:

> DFnew 
     Date FS FIIB 
1 1/31/2000 99.87 <NA> 
2 1/31/2005 <NA> 107.68 
3 10/29/2004 <NA> 103.24 
4 10/30/2004 <NA> 104.82 
5 12/31/2004 <NA> 105.14 
6 2/29/2000 99.97 <NA> 

正如你可以看到,這給出了相同的結果(儘管順序不同)。這種方法假定其餘的格式不正確的數據幀與示例數據幀具有相同的結構。


最後,根據Date得到一切都在正確的類和訂購新的數據框:

# set column classes 
DFnew[] <- lapply(DFnew, type.convert) 
# change the 'Date'-column to date-format 
DFnew$Date <- as.Date(DFnew$Date, format = '%m/%d/%Y') 
# set the order 
DFnew <- DFnew[order(DFnew$Date),] 

這給:

> DFnew 
     Date FS FIIB 
1 2000-01-31 99.87  NA 
6 2000-02-29 99.97  NA 
3 2004-10-29 NA 103.24 
4 2004-10-30 NA 104.82 
5 2004-12-31 NA 105.14 
2 2005-01-31 NA 107.68 
+0

是的,數據格式是可怕的,我不能做任何事情的來源。這就是爲什麼我正在尋找一種更好地格式化結果的方法。感謝您的指導。 –

+0

我只是在做我的數據集的實驗。我有超過100列與此類似。有沒有更好的方法來提取列而不是使用1:2,3:4等等?謝謝! –

+0

@ T-T查看更新HTH。 – Jaap