R语言 如何在一列中找到最高(最晚)和最低(最早)日期?

pprl5pva  于 2023-05-04  发布在  其他
关注(0)|答案(4)|浏览(408)

我试图将dataframe中的两个列转换为“好”的日期和时间类,直到现在还没有取得多大成功。我尝试了各种类(timeDateDatetimeSeriesPOSIXctPOSIXlt),但没有成功。也许我只是忽略了明显的,因为我已经尝试了这么多的方法,我只是不知道什么是什么了。我希望你们中的一些人能对我的错误之处有所启发。

目标:我想用最早和最晚的日期计算两个日期之间的差值。我使用head()tail()得到了这个值,但是因为这些值不一定是数据中的最早和最晚日期,所以我需要另一种方法。(我无法让数据排序工作,因为它只在日期当天对数据进行排序。)
第二目标:我想转换日期从每日格式(i.即8-12-2010)到每周、每月和每年的水平(即8-12-2010)。即‘49- 2010’、‘December-10’和仅仅‘2010’)。这可以通过格式设置(如%d-%m-%y)来完成。这可以通过转换数据来完成。帧转换为时间类,然后将时间类转换为正确的格式((8-12-2010 -> format("%B-%y") -> 'december-10'),然后将该时间类转换为每个月的水平因子?

对于这两个目标,我需要以某种方式将日期框转换为时间类,这就是我遇到一些困难的地方。
我的dataframe看起来像这样:

> 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包有一个“range”函数,但是,转换为Date类适用于单个示例,但由于某种原因不适用于 Dataframe :

> 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"

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

eagi6jfj

eagi6jfj1#

从一些虚拟数据开始:

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更改为%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 ...
tjrkku2a

tjrkku2a2#

简短回答:

  • 如果尚未转换为日期,请转换为日期。
  • 然后在日期列表中使用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"
mccptt67

mccptt673#

以下是tidyverse解决方案:

library(dplyr)

df <- data.frame(dates = structure(c(15401, 15405, 15505, 16506), class = "Date"))
df
#>        dates
#> 1 2012-03-02
#> 2 2012-03-06
#> 3 2012-06-14
#> 4 2015-03-12

# earliest and oldest dates in this order 
# diff is the difference between earliest and oldest dates
df %>%
  arrange(desc(df)) %>%
  slice(c(1, nrow(.))) %>%
  mutate(diff = lag(dates) - dates)
#>        dates      diff
#> 1 2015-03-12   NA days
#> 2 2012-03-02 1105 days

创建于2023-05-01使用reprex v2.0.2

n9vozmp4

n9vozmp44#

更简单。在日期列上使用summary()直接给出Min和Max等。示例:summary(df$date)

相关问题