16

如何在R中的年,月,日和日期之间转换?

我知道可以通过字符串来做到这一点,但我宁愿避免转换为字符串,部分原因可能是性能受到影响?部分原因是我担心区域化问题,其中一些世界使用“年-月-日” ”,有些使用“年-日-月”。

看起来 ISODate 提供了方向 year,month,day -> DateTime ,尽管它确实首先将数字转换为字符串,所以如果有一种方法不通过字符串,那么我更喜欢。

从日期时间到数值,我找不到任何相反的东西?我宁愿不需要使用 strsplit 或类似的东西。

编辑:为了清楚起见,我所拥有的是一个数据框,它看起来像:

year month day hour somevalue
2004 1     1   1   1515353
2004 1     1   2   3513535
....

我希望能够自由转换成这种格式:

time(hour units) somevalue
1             1515353
2             3513535
....

...并且还能够再次返回。

编辑:为了消除对“时间”(小时单位)含义的一些混淆,最终我所做的是,并使用如何在 R 中找到两个日期之间的差异的信息?

前进方向:

lh$time <- as.numeric( difftime(ISOdate(lh$year,lh$month,lh$day,lh$hour), ISOdate(2004,1,1,0), units="hours"))
lh$year <- NULL; lh$month <- NULL; lh$day <- NULL; lh$hour <- NULL

向后方向:

...好吧,我还没有倒退,但我想像:

  • 从 lh$time 创建 difftime 对象(不知何故...)
  • 将 ISOdate(2004,1,1,0) 添加到 difftime 对象
  • 使用以下解决方案之一来获取年、月、日、小时

我想在未来,我可以问我要解决的确切问题,但我试图将我的具体问题分解为通用的可重用问题,但也许这是一个错误?

4

3 回答 3

24

因为有很多方法可以从文件、数据库等中传递日期,并且由于您提到只是以不同的顺序或使用不同的分隔符编写的原因,将输入的日期表示为字符串是一种方便且有用的方法解决方案。R 不将实际日期保存为字符串,您无需将它们作为字符串处理即可使用它们。

R 在内部使用操作系统以标准方式执行这些操作。你根本不需要操作字符串——也许只是将一些东西从字符转换为它们的数字等价物。例如,很容易将两个操作(向前和向后)封装在您可以部署的简单函数中。

toDate <- function(year, month, day) {
    ISOdate(year, month, day)
}

toNumerics <- function(Date) {
    stopifnot(inherits(Date, c("Date", "POSIXt")))
    day <- as.numeric(strftime(Date, format = "%d"))
    month <- as.numeric(strftime(Date, format = "%m"))
    year <- as.numeric(strftime(Date, format = "%Y"))
    list(year = year, month = month, day = day)
}

我放弃了对分隔字符的单个调用strptime()和随后的拆分,因为您不喜欢这种操作。

> toDate(2004, 12, 21)
[1] "2004-12-21 12:00:00 GMT"
> toNumerics(toDate(2004, 12, 21))
$year
[1] 2004

$month
[1] 12

$day
[1] 21

在内部,R 的日期时间代码运行良好,并且如果由于时区问题等原因在某些地方有点复杂,则经过良好测试和鲁棒性。我发现使用的习惯用法toNumerics()比将日期时间作为列表并记住哪些元素是基于 0 的更直观。建立在提供的功能上似乎比试图避免字符串转换等更容易。

于 2012-10-19T15:29:20.797 回答
12

我参加聚会有点晚了,但是从整数转换为日期的另一种方法是lubridate::make_date函数。请参阅以下来自 R for Data Science 的示例:

library(lubridate)
library(nycflights13)
library(tidyverse)

a <- flights %>%
  mutate(date = make_date(year, month, day))
于 2017-04-11T09:38:54.603 回答
4

找到了一种从日期到年、月、日的解决方案。

假设我们有一个日期对象,我们将在这里使用 ISOdate 创建它:

somedate <- ISOdate(2004,12,21)

然后,我们可以得到 this 的数值成分如下:

unclass(as.POSIXlt(somedate))

给出:

$sec
[1] 0

$min
[1] 0

$hour
[1] 12

$mday
[1] 21

$mon
[1] 11

$year
[1] 104

然后可以得到想要的东西,例如:

unclass(as.POSIXlt(somedate))$mon

注意 $year 是 [实际年份] - 1900,month 从 0 开始,mday 从 1 开始(根据 POSIX 标准)

于 2012-10-19T14:47:12.953 回答