简体   繁体   English

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

[英]How to convert in both directions between year,month,day and dates in R?

How to convert between year,month,day and dates in R? 如何在R中转换年,月,日和日期?

I know one can do this via strings, but I would prefer to avoid converting to strings, partly because maybe there is a performance hit?, and partly because I worry about regionalization issues, where some of the world uses "year-month-day" and some uses "year-day-month". 我知道人们可以通过字符串来做到这一点,但我宁愿避免转换为字符串,部分是因为可能会有性能损失?部分是因为我担心区域化问题,世界上有些人使用“年 - 月 - 日” “有些人使用”年 - 月 - 月“。

It looks like ISODate provides the direction year,month,day -> DateTime , although it does first converts the number to a string, so if there is a way that doesn't go via a string then I prefer. 看起来ISODate提供方向年,月,日 - > DateTime,虽然它首先将数字转换为字符串,所以如果有一种方法不通过字符串,那么我更喜欢。

I couldn't find anything that goes the other way, from datetimes to numerical values? 从日期时间到数值,我找不到任何其他方面的东西? I would prefer not needing to use strsplit or things like that. 我宁愿不需要使用strsplit或类似的东西。

Edit: just to be clear, what I have is, a data frame which looks like: 编辑:为了清楚,我所拥有的是一个数据框,看起来像:

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

I want to be able to freely convert to this format: 我希望能够自由转换为这种格式:

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

... and also be able to go back again. ......还能再次回去。

Edit: to clear up some confusion on what 'time' (hour units) means, ultimately what I did was, and using information from How to find the difference between two dates in hours in R? 编辑:清除一些关于'时间'(小时单位)意味着什么的混淆,最终我做了什么,并使用如何找到R中两个小时之间的差异的信息 :

forwards direction: 前进方向:

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

backwards direction: 向后方向:

... well, I didnt do backwards yet, but I imagine something like: ......好吧,我还没做倒退,但我想象的是:

  • create difftime object out of lh$time (somehow...) 用lh $ time创建difftime对象(不知怎的......)
  • add ISOdate(2004,1,1,0) to difftime object 将ISOdate(2004,1,1,0)添加到difftime对象
  • use one of the solution below to get the year,month,day, hour back 使用下面的解决方案之一来获得年,月,日,小时

I suppose in the future, I could ask the exact problem I'm trying to solve, but I was trying to factorize my specific problem into generic reusable questions, but maybe that was a mistake? 我想在将来,我可以问我正在尝试解决的确切问题,但我试图将我的具体问题分解为通用的可重用问题,但也许这是一个错误?

Because there are so many ways in which a date can be passed in from files, databases etc and for the reason you mention of just being written in different orders or with different separators, representing the inputted date as a character string is a convenient and useful solution. 因为有很多方法可以从文件,数据库等传递日期,并且因为你提到只是用不同的顺序或不同的分隔符编写,将输入的日期表示为字符串是一个方便和有用的解。 R doesn't hold the actual dates as strings and you don't need to process them as strings to work with them. R不将实际日期保存为字符串,您不需要将它们作为字符串处理以使用它们。

Internally R is using the operating system to do these things in a standard way. 内部R使用操作系统以标准方式执行这些操作。 You don't need to manipulate strings at all - just perhaps convert some things from character to their numerical equivalent. 你根本不需要操纵字符串 - 只是将一些东西从字符转换为它们的数字等价物。 For example, it is quite easy to wrap up both operations (forwards and backwards) in simple functions you can deploy. 例如,在您可以部署的简单函数中包含两个操作(前向和后向)非常容易。

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)
}

I forego the a single call to strptime() and subsequent splitting on a separation character because you don't like that kind of manipulation. 我放弃了对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

Internally R's datetime code works well and is well tested and robust if a bit complex in places because of timezone issues etc. I find the idiom used in toNumerics() more intuitive than having a date time as a list and remembering which elements are 0-based. 内部R的日期时间代码运行良好,经过充分测试和稳健,如果由于时区问题等在某些地方有点复杂我发现使用toNumerics()的习惯用法比将日期时间作为列表更直观并且记住哪些元素是0-根据。 Building on the functionality provided would seem easier than trying to avoid string conversions etc. 基于所提供的功能看起来比试图避免字符串转换等更容易。

Found one solution for going from date to year,month,day. 找到一个从日期到年,月,日的解决方案。

Let's say we have a date object, that we'll create here using ISOdate: 假设我们有一个日期对象,我们将使用ISOdate在这里创建:

somedate <- ISOdate(2004,12,21)

Then, we can get the numerical components of this as follows: 然后,我们可以得到如下的数字组件:

unclass(as.POSIXlt(somedate))

Gives: 得到:

$sec
[1] 0

$min
[1] 0

$hour
[1] 12

$mday
[1] 21

$mon
[1] 11

$year
[1] 104

Then one can get what one wants for example: 然后就可以得到一个人想要的例子:

unclass(as.POSIXlt(somedate))$mon

Note that $year is [actual year] - 1900, month is 0-based, mday is 1-based (as per the POSIX standard) 请注意,$ year是[实际年份] - 1900,月份是0,mday是1(根据POSIX标准)

I'm a bit late to the party, but one other way to convert from integers to date is the lubridate::make_date function. 我参加聚会有点晚了,但是从整数到日期转换的另一种方法是lubridate::make_date函数。 See the example below from R for Data Science: 请参阅以下R中的数据科学示例:

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

a <- flights %>%
  mutate(date = make_date(year, month, day))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM