如何找到最高(最新)和最低(最早)日期 [R]
Posted
技术标签:
【中文标题】如何找到最高(最新)和最低(最早)日期 [R]【英文标题】:How to find the highest (latest) and lowest (earliest) date [R] 【发布时间】:2011-05-22 03:09:53 【问题描述】:我正在尝试将我的数据框中的两列转换为“良好”的日期和时间类,但到目前为止还没有取得太大的成功。我尝试了各种课程(timeDate
、Date
、timeSeries
、POSIXct
、POSIXlt
)但没有成功。也许我只是忽略了显而易见的事情,因为我尝试了很多方法,我只是不知道什么是什么了。我希望你们中的一些人能阐明我哪里出错了。
目标:
我想使用最早和最晚日期计算两个日期之间的差异。我使用head()
和tail()
进行了这项工作,但因为这些值不是我数据中最早和最晚日期的必要条件,所以我需要另一种方法。 (我无法对数据进行排序,因为它仅在日期当天对数据进行排序。)
第二个目标:我想将日期从每日格式(即 8-12-2010)转换为每周、每月和每年的级别(即 '49-2010'、'december-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 包有一个“范围”功能,但是,转换为 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"
在这一点上,我几乎相信这是不可能的,所以任何想法都将受到高度赞赏!
问候,
【问题讨论】:
您可以使用dput(tmpTimes4)
在您的代码中提供准确的数据集使用。
@Marek:感谢您的回复!我不知道 dput,所以谢谢你的提示。 :)
【参考方案1】:
从一些虚拟数据开始:
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), min(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
更改为 @987654336 @。 ?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 ...
【讨论】:
哇,加文,非常感谢!你真的帮助了我,不仅仅是代码示例,还有优秀(清晰)的文本。再次感谢,我现在完全明白了,并且成功地计算了天数,转换了日期,并显示了每个时间段的结果。是的! :) @Jura25:很高兴你发现它有用。 确实,最小值和最大值适用于日期,但如果您的日期列中有任何 NA,请使用 na.rm=TRUE 例如星号 @PanchoMulongeni Date 变量中NA
的唯一原因是日期无效(即格式不正确,或日期不存在)。我不认为忽略这是一件好事,你应该调查为什么NA
s 在那里。如果它们在那里是因为您没有记录日期,那么也要摆脱它们;如果您不知道日期,则数据无用。
@GavinSimpson。很好的答案。 "> with(tmpTimes, difftime(max(EntryTime), main(EntryTime))) 中的小错字 14 天的时差”认为应该是 min() 而不是 main()?【参考方案2】:
简答:
如果尚未完成,请转换为日期。然后在列表中使用 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"
【讨论】:
【参考方案3】:更容易。在日期列上使用summary()
直接给出最小值和最大值等。示例:summary(df$date)
【讨论】:
这看起来更像是评论而不是答案以上是关于如何找到最高(最新)和最低(最早)日期 [R]的主要内容,如果未能解决你的问题,请参考以下文章