2010-12-08 159 views
18

我試圖將我的數據框中的兩列轉換爲'好'日期&時間類,直到現在還沒有太多成功用它。我嘗試了各種類(timeDate,Date,timeSeries,POSIXct,POSIXlt),但沒有成功。也許我只是忽略了明顯的,因爲我已經嘗試了很多方法,我只是不知道什麼是什麼。我希望你們中的一些人能夠闡明我出錯的地方。如何查找最高(最新)和最低(最早)日期[R]

目標: 我想使用最早和最近的日期來計算兩個日期之間的差異。我使用head()和tail()來處理這個問題,但是因爲這些值在我的數據中並不是必需的,所以我需要另一種方法。 (我無法讓數據的排序工作,因爲它僅在日期當天對數據進行排序。)

第二個目標:我想將日期從日常格式(即8-12 -2010)到每週,每月和每年的水平(即「49 -2010」,「十二月-10」和「2010」)。這可以通過格式設置來完成(如「%d-%m-%y」)。這可以通過將data.frame轉換爲時間類來完成,而不是以正確的格式(8-12-2010 - > format(「%B-%y」) - >'December-10')轉換時間類。 ,然後將那個時間課程轉換爲每個月級別的因子?

對於這兩個目標,我需要以某種方式將日期框架轉換爲時間類,這是我遇到一些困難的地方。

我的數據框看起來是這樣的:

> tradesList[c(1,10,11,20),14:15] -> tmpTimes4 
> tmpTimes4 
    EntryTime ExitTime 
1 01-03-07 10-04-07 
10 29-10-07 02-11-07 
11 13-04-07 14-05-07 
20 18-12-07 20-02-08 

這裏是什麼,我已經試過了總結:

> class(tmpTimes4) 
[1] "data.frame" 
> as.Date(head(tmpTimes4$EntryTimes, n=1), format="%d-%m-%y") 
Error in as.Date.default(head(tmpTimes4$EntryTimes, n = 1), format = "%d-%m-%y") : 
    do not know how to convert 'head(tmpTimes4$EntryTimes, n = 1)' to class "Date" 
> as.timeDate(tmpTimes4, format="%d-%m-%y") 
Error in as.timeDate(tmpTimes4, format = "%d-%m-%y") : 
    unused argument(s) (format = "%d-%m-%y") 
> timeSeries(tmpTimes4, format="%d-%m-%y") 
Error in midnightStandard2(charvec, format) : 
    'charvec' has non-NA entries of different number of characters 
> tmpEntryTimes4 <- timeSeries(tmpTimes4$EntryTime, format="%d-%m-%y") 
> tmpExitTimes4 <- timeSeries(tmpTimes4$ExitTime, format="%d-%m-%y") 
> tmpTimes5 <- cbind(tmpEntryTimes4,tmpExitTimes4) 
> colnames(tmpTimes5) <- c("Entry","Exit") 
> tmpTimes5 
    Entry Exit  
[1,] 01-03-07 10-04-07 
[2,] 29-10-07 02-11-07 
[3,] 13-04-07 14-05-07 
[4,] 18-12-07 20-02-08 
> class(tmpTimes5) 
[1] "timeSeries" 
attr(,"package") 
[1] "timeSeries" 
> as.timeDate(tmpTimes5, format="%d-%m-%y") 
Error in as.timeDate(tmpTimes5, format = "%d-%m-%y") : 
    unused argument(s) (format = "%d-%m-%y") 
> as.Date(tmpTimes5, format="%d-%m-%y") 
Error in as.Date.default(tmpTimes5, format = "%d-%m-%y") : 
    do not know how to convert 'tmpTimes5' to class "Date" 
> format.POSIXlt(tmpTimes5, format="%d-%m-%y", usetz=FALSE) 
Error in format.POSIXlt(tmpTimes5, format = "%d-%m-%y", usetz = FALSE) : 
    wrong class 
> as.POSIXlt(tmpTimes5, format="%d-%m-%y", usetz=FALSE) 
Error in as.POSIXlt.default(tmpTimes5, format = "%d-%m-%y", usetz = FALSE) : 
    do not know how to convert 'tmpTimes5' to class "POSIXlt" 
> as.POSIXct(tmpTimes5, format="%d-%m-%y", usetz=FALSE) 
Error in as.POSIXlt.default(x, tz, ...) : 
    do not know how to convert 'x' to class "POSIXlt" 

的TIMEDATE包有「範圍」的功能,但是,轉換爲日期類適用於單個實例,但出於某種原因不適用於數據框:

> as.Date(tmpTimes4[1,1], format="%d-%m-%y") 
[1] "2007-03-01" 
> as.Date(tmpTimes4, format="%d-%m-%y") 
Error in as.Date.default(tmpTimes4, format = "%d-%m-%y") : 
    do not know how to convert 'tmpTimes4' to class "Date" 

在這一點上,我幾乎相信這是不可能做到的,所以任何想法都會受到高度讚賞!

問候,

+0

你可以使用`dput(tmpTimes4)`來提供你的代碼的確切數據集中使用。 – Marek 2010-12-08 11:38:22

+0

@Marek:感謝您的回覆!我不知道dput,所以謝謝小費。 :) – Jura25 2010-12-08 13:40:32

回答

30

開始用一些虛擬的數據:

start <- as.Date("2010/01/01") 
end <- as.Date("2010/12/31") 
set.seed(1) 
datewant <- seq(start, end, by = "days")[sample(15)] 
tmpTimes <- data.frame(EntryTime = datewant, 
         ExitTime = datewant + sample(100, 15)) 
## reorder on EntryTime so in random order 
tmpTimes <- tmpTimes[sample(NROW(tmpTimes)), ] 
head(tmpTimes) 

,所以我們有這樣的事情:

> head(tmpTimes) 
    EntryTime ExitTime 
8 2010-01-14 2010-03-16 
9 2010-01-05 2010-01-17 
7 2010-01-10 2010-01-30 
3 2010-01-08 2010-04-16 
10 2010-01-01 2010-01-26 
13 2010-01-12 2010-02-15 

使用上面,看目標1,計算差異在最早和最近的日期之間。你可以把日期看作是數字(這是他們如何存儲在內部),所以像min()max()這樣的函數將起作用。您可以使用difftime()功能:

> with(tmpTimes, difftime(max(EntryTime), main(EntryTime))) 
Time difference of 14 days 

或使用標準的減法

> with(tmpTimes, max(EntryTime) - min(EntryTime)) 
Time difference of 14 days 

獲得天的差別。 head()tail()只在排序日期時才起作用,因爲這些日期是向量中的第一個和最後一個值,而不是最高和最低的實際值。

目標2:您似乎試圖將數據幀轉換爲日期。你不能這樣做。你可以做的是重新格式化數據幀的組件中的數據。在此,我通過將EntryTime列重新格式化爲日期的幾個不同摘要來向tmpTimes添加列。

tmpTimes2 <- within(tmpTimes, weekOfYear <- format(EntryTime, format = "%W-%Y")) 
tmpTimes2 <- within(tmpTimes2, monthYear <- format(EntryTime, format = "%B-%Y")) 
tmpTimes2 <- within(tmpTimes2, Year <- format(EntryTime, format = "%Y")) 

,並提供:

> head(tmpTimes2) 
    EntryTime ExitTime weekOfYear monthYear Year 
8 2010-01-14 2010-03-16 02-2010 January-2010 2010 
9 2010-01-05 2010-01-17 01-2010 January-2010 2010 
7 2010-01-10 2010-01-30 01-2010 January-2010 2010 
3 2010-01-08 2010-04-16 01-2010 January-2010 2010 
10 2010-01-01 2010-01-26 00-2010 January-2010 2010 
13 2010-01-12 2010-02-15 02-2010 January-2010 2010 

如果你是美國人還是希望使用美國通用的一週的開始(%W開始的一週上週一,在美國的慣例是開始於星期日),將%W更改爲%U?strftime有關於%W%U所代表的更多細節。


上的數據格式的最後一點:在上述我與在標準的R格式的日期工作。您可以將數據以非標準標記的形式存儲在數據框中,推測可能是字符或因素。所以你有這樣的東西:

tmpTimes3 <- within(tmpTimes, 
        EntryTime <- format(EntryTime, format = "%d-%m-%y")) 
tmpTimes3 <- within(tmpTimes3, 
        ExitTime <- format(ExitTime, format = "%d-%m-%y")) 

> head(tmpTimes3) 
    EntryTime ExitTime 
8 14-01-10 16-03-10 
9 05-01-10 17-01-10 
7 10-01-10 30-01-10 
3 08-01-10 16-04-10 
10 01-01-10 26-01-10 
13 12-01-10 15-02-10 

你需要將這些字符或因素轉換爲R理解爲日期的東西。我喜歡的是"Date"類。在嘗試與您的數據上面的答案,你的數據轉化成正確的格式:

tmpTimes3 <- 
    within(tmpTimes3, { 
      EntryTime <- as.Date(as.character(EntryTime), format = "%d-%m-%y") 
      ExitTime <- as.Date(as.character(ExitTime), format = "%d-%m-%y") 
      }) 

,使您的數據是這樣的:

> head(tmpTimes3) 
    EntryTime ExitTime 
8 2010-01-14 2010-03-16 
9 2010-01-05 2010-01-17 
7 2010-01-10 2010-01-30 
3 2010-01-08 2010-04-16 
10 2010-01-01 2010-01-26 
13 2010-01-12 2010-02-15 
> str(tmpTimes3) 
'data.frame': 15 obs. of 2 variables: 
$ EntryTime:Class 'Date' num [1:15] 14623 14614 14619 14617 14610 ... 
$ ExitTime :Class 'Date' num [1:15] 14684 14626 14639 14715 14635 ... 
5

簡短的回答:

  • 轉換如果還沒有完成的話。
  • 然後使用日期的列表 中的最小值和最大值。

    date_list = structure(c(15401, 15405, 15405), class = "Date") 
    date_list 
    #[1] "2012-03-02" "2012-03-06" "2012-03-06" 
    
    min(date_list) 
    #[1] "2012-03-02" 
    max(date_list) 
    #[1] "2012-03-06"