繁体   English   中英

处理R中的数字(十进制)日期?

[英]Dealing with numeric (decimal) dates in R?

我有一些来自Excel的数字日期数据:

> df <- data.frame(c(42613, 42612, 42614), c(42614.61, 42613.97, 42612.12))
> names(df) <- c("Closetime", "Opentime")

ClosetimeOpentime都是numeric 我想保留来自OpenTime的小时/分钟/秒数据,并将时间'00:00:00'添加到Closetime每个日期:

> df$Closetime <- paste(as.Date(df$Closetime, origin = '1900-01-01'), c('00:00:00'))

执行Closetime足够Closetime ,但是当我尝试在Opentime上使用lubridate::date_decimal时,一切都会lubridate::date_decimal Opentime

> df$Opentime <- date_decimal(df$Opentime)
> df
            Closetime             Opentime
1 2016-09-02 00:00:00 42614-08-11 15:36:00
2 2016-09-01 00:00:00 42613-12-21 01:12:00
3 2016-09-03 00:00:00 42612-02-13 22:04:48

我如何才能使OpentimeClosetime具有相同的类型/格式? 我最终希望能够获得小时数之间的差异,以供参考。

如果可以使用POSIXct,则可以例如

df$Opentime <- as.POSIXct( df$Opentime*24*60*60, 
                origin="1900-01-01", 
                tz="UTC")

推理:POSIXct只是从开始到现在的秒数

首先,我们遵循help("as.Date")有关Excel日期的建议。 我在这里假设Windows Excel:

df$Closetime_p <- as.Date(df$Closetime, origin = "1899-12-30")
df$Opentime_p <- as.Date(floor(df$Opentime), origin = "1899-12-30")

然后我们转换为POSIXct:

df$Closetime_p <- as.POSIXct(as.POSIXlt(df$Closetime_p, tz = "GMT"), tz = "GMT")
df$Opentime_p <- as.POSIXct(as.POSIXlt(df$Opentime_p, tz = "GMT"), tz = "GMT")

现在我们添加时间:

df$Opentime_p <- df$Opentime_p + (df$Opentime - floor(df$Opentime)) * 24 * 3600
#  Closetime Opentime Closetime_p          Opentime_p
#1     42613 42614.61  2016-08-31 2016-09-01 14:38:24
#2     42612 42613.97  2016-08-30 2016-08-31 23:16:48
#3     42614 42612.12  2016-09-01 2016-08-30 02:52:48

转换为日期,然后转换为POSIXct

首先,创建data.frame(并注意我们如何设置列名称):

R> df <- data.frame(CloseT=c(42613, 42612, 42614), OpenT=c(42614.61, 42613.97, 42612.12))
R> df
  CloseT   OpenT
1  42613 42614.6
2  42612 42614.0
3  42614 42612.1
R> 

然后转换为日期:

R> df$CloseT <- as.Date(df$CloseT, origin="1900-01-01")
R> df$OpenT <- as.Date(df$OpenT, origin="1900-01-01")
R> df
      CloseT      OpenT
1 2016-09-02 2016-09-03
2 2016-09-01 2016-09-02
3 2016-09-03 2016-09-01
R>

最后,转换为POSIXct

R> df$OpenT <- as.POSIXct(df$OpenT)
R> df$CloseT <- as.POSIXct(df$CloseT)
R> df
               CloseT               OpenT
1 2016-09-01 19:00:00 2016-09-03 09:38:24
2 2016-08-31 19:00:00 2016-09-02 18:16:48
3 2016-09-02 19:00:00 2016-08-31 21:52:48
R> 

如Roland所示,通过POSIXlt可以设置时区。

查看有关date_decimal的文档:

一个POSIXct对象,其年份对应于小数的整数部分。

date <- ymd("2009-02-10")
decimal <- decimal_date(date)  # 2009.11
date_decimal(decimal) # "2009-02-10 UTC"

因此,在您的示例中,它会将42614解释为年份。

尝试使用as.POSIXct 您可能必须指定时区,但是如果您只需要增量,则不需要。 下面我计算了时差:

df <- data.frame(c(42613, 42612, 42614), c(42614.61, 42613.97, 42612.12))
names(df) <- c("Closetime", "Opentime")
df$Closetime <- as.POSIXct(as.Date(df$Closetime, origin = '1900-01-01'))
df$Opentime <- as.POSIXct(as.Date(df$Opentime, origin = '1900-01-01'))
df$delta <- df$Opentime - df$Closetime
df
            Closetime            Opentime      delta
1 2016-09-01 20:00:00 2016-09-03 10:38:24  1.61 days
2 2016-08-31 20:00:00 2016-09-02 19:16:48  1.97 days
3 2016-09-02 20:00:00 2016-08-31 22:52:48 -1.88 days

根据注释,如果要确保显示的小时数正确,则需要正确匹配时区。 您可以在转换为as.POSIXct通过设置tzone属性来执行此操作。

df <- data.frame(c(42613, 42612, 42614), c(42614.61, 42613.97, 42612.12))
names(df) <- c("Closetime", "Opentime")
df$Closetime <- as.POSIXct(as.Date(df$Closetime, origin = '1900-01-01'))
df$Opentime <- as.POSIXct(as.Date(df$Opentime, origin = '1900-01-01'))
attr(df$Closetime, "tzone") <- "GMT"
attr(df$Opentime, "tzone") <- "GMT"
df$delta <- df$Opentime - df$Closetime
df

   Closetime            Opentime      delta
1 2016-09-02 2016-09-03 14:38:24  1.61 days
2 2016-09-01 2016-09-02 23:16:48  1.97 days
3 2016-09-03 2016-09-01 02:52:48 -1.88 days

暂无
暂无

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

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