2010-12-08 110 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"