如何找到最高(最新)和最低(最早)的日期[R]

Jur*_*ura 26 time datetime r

我正在尝试将我的数据框中的两列转换为"好"的日期和时间类,直到现在它并没有取得多大成功.我已经试过各种类别(timeDate,Date,timeSeries,POSIXct,POSIXlt),但没有成功.也许我只是忽略了显而易见的事情,因为我已经尝试了很多方法,我只是不知道它是什么了.我希望你们中的一些人可以了解我哪里出错了.

目标:我想使用最早和最晚的日期来计算两个日期之间的差异.我得到了这个head()tail(),但由于这些值不是我数据中最早和最晚的日期,我需要另一种方式.(我无法对数据进行排序,因为它只在日期当天对数据进行排序.)

第二个目标:我想将日期格式(即8-12-2010)转换为每周,每月和每年的水平(即'49 -2010','12月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
Run Code Online (Sandbox Code Playgroud)

以下是我尝试过的摘要:

> 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"
Run Code Online (Sandbox Code Playgroud)

TimeDate包具有'range'函数,但是,转换为Date类适用于单个实例,但由于某种原因不适用于数据框:

> 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"
Run Code Online (Sandbox Code Playgroud)

在这一点上,我几乎认为这是不可能做到的,所以任何想法都会受到高度赞赏!

问候,

Rei*_*son 35

从一些虚拟数据开始:

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)
Run Code Online (Sandbox Code Playgroud)

所以我们有这样的事情:

> 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
Run Code Online (Sandbox Code Playgroud)

使用上述内容,查看目标1,计算最早和最晚日期之间的差异.您可以将日期视为数字(这就是它们在内部存储的方式),因此函数类似于min()并且max()将起作用.你可以使用这个difftime()功能:

> with(tmpTimes, difftime(max(EntryTime), min(EntryTime)))
Time difference of 14 days
Run Code Online (Sandbox Code Playgroud)

或使用标准减法

> with(tmpTimes, max(EntryTime) - min(EntryTime))
Time difference of 14 days
Run Code Online (Sandbox Code Playgroud)

在几天内获得差异.head()并且tail()只有在对日期进行排序时才会起作用,因为它们采用向量中的第一个和最后一个值,而不是最高和最低实际值.

目标2:您似乎正在尝试将数据框转换为日期.你不能这样做.您可以做的是重新格式化数据框组件中的数据.在这里,我通过将列tmpTimes重新格式化EntryTime为几个不同的日期摘要来添加列.

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"))
Run Code Online (Sandbox Code Playgroud)

赠送:

> 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
Run Code Online (Sandbox Code Playgroud)

如果您是美国人或想要在本周%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
Run Code Online (Sandbox Code Playgroud)

您需要将这些字符或因子转换为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")
           })
Run Code Online (Sandbox Code Playgroud)

这样你的数据就像这样:

> 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 ...
Run Code Online (Sandbox Code Playgroud)

  • 实际上,最小值和最大值适用于日期,但如果您的日期列中有任何NA,则请使用na.rm = TRUE,例如stardate <-min(DateofTest,na.rm = TRUE).保护自己头上的困惑划痕. (2认同)

tuc*_*son 10

简短回答:

  • 如果尚未完成,则转换为日期.
  • 然后在日期列表中使用min和max.

    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"
    
    Run Code Online (Sandbox Code Playgroud)