在R中计算时间差

29

我有一份包含超过3百万条记录的数据,其中start.time和end.time是两个变量。前10个记录如下:

   start.date start.time   end.date end.time
1  2012-07-13   15:01:32 2012-07-13 15:02:42
2  2012-07-05   18:26:31 2012-07-05 18:27:19
3  2012-07-14   20:23:21 2012-07-14 20:24:11
4  2012-07-29   16:09:54 2012-07-29 16:10:48
5  2012-07-21   14:58:32 2012-07-21 15:00:17
6  2012-07-04   15:36:31 2012-07-04 15:37:11
7  2012-07-22   18:28:31 2012-07-22 18:28:50
8  2012-07-09   21:08:42 2012-07-09 21:09:02
9  2012-07-05   09:44:52 2012-07-05 09:45:05
10 2012-07-02   18:50:47 2012-07-02 18:51:38

我需要计算开始时间和结束时间之间的差值。

我使用了以下代码:

mbehave11$diff.time <- difftime(mbehave11$end.time, mbehave11$start.time, units="secs")

但是我遇到了这个错误:

Error in as.POSIXlt.character(x, tz, ...) : 
  character string is not in a standard unambiguous format
In addition: Warning messages:
1: In is.na.POSIXlt(strptime(xx, f <- "%Y-%m-%d %H:%M:%OS", tz = tz)) :
  Reached total allocation of 1535Mb: see help(memory.size)

你可以提供一个可复制的实例吗?你可以阅读这个链接获取更多信息:https://dev59.com/eG025IYBdhLWcg3whGSx - Dason
2个回答

47

在进行日期/时间运算之前,您必须将字符串转换为日期对象。请尝试以下操作:

a)读取您的数据:

R> dat <- read.table(textConnection("start.date start.time end.date end.time
2012-07-13   15:01:32 2012-07-13 15:02:42
2012-07-05   18:26:31 2012-07-05 18:27:19 
2012-07-14   20:23:21 2012-07-14 20:24:11"), header=TRUE) 
b) 只针对一个观察对象进行操作:
 R>  strptime( paste(dat[,1], dat[,2]), "%Y-%m-%d %H:%M:%S")
 [1] "2012-07-13 15:01:32" "2012-07-05 18:26:31" "2012-07-14 20:23:21" 

c) 在数据集上工作,将其转换为数字:

 R> as.numeric(difftime(strptime(paste(dat[,1],dat[,2]),"%Y-%m-%d %H:%M:%S"),
                        strptime(paste(dat[,3],dat[,4]),"%Y-%m-%d %H:%M:%S"))) 
 [1] -70 -48 -50
 R> 

编辑以下内容是另一位用户在七年后提供的。

d) 简单解释一下上面的结果 -70 -48 -50,请逐行查看示例:

[2012-07-13 15:01:32] - [2012-07-13 15:02:42] = -70 seconds,  
[2012-07-05 18:26:31] - [2012-07-05 18:27:19] = -48 seconds,  
[2012-07-14 20:23:21] - [2012-07-14 20:24:11] = -50 seconds

1
但是这个结果意味着什么呢?我的意思是,结果是-70 -48 -50.. 我该如何将它们解释为分钟差异? - user1702490
10
请查看help(difftime) -- 有一个默认为秒(second)的单位参数(units argument),您可以覆盖它。但是,仅仅为了确认,请看第一行中的-70并考虑您设置的第一行中的时间差:七十秒。如果你想要分钟(minuts),请使用units="min"。很简单。 - Dirk Eddelbuettel
更新了答案以显示结果的含义,因为我也花了一些时间才弄明白。 - Denis
通常我不喜欢其他人在没有明确告知的情况下编辑我的答案。你可以随时用你的名字发布新的回答,这样更清晰明了。 - Dirk Eddelbuettel

6

我认为你可以使用lubridate包
它有一个叫ymd_hms的方法
你可以用它从字符串中获取时间: 对于大数据集,它会更快

library(lubridate)
dat <- read.table(textConnection("start.date start.time end.date end.time
2012-07-13   15:01:32 2012-07-13 15:02:42
2012-07-05   18:26:31 2012-07-05 18:27:19 
2012-07-14   20:23:21 2012-07-14 20:24:11"), header=TRUE)
starttime = ymd_hms(paste(dat[,1], dat[,2]))
endtime = ymd_hms(paste(dat[,3], dat[,4]))
interval = difftime(endtime,starttime,units = "secs")

或者您可以在一行中完成,但是对于大数据集需要更长时间:

difftime(paste(dat[,3], dat[,4]),paste(dat[,1], dat[,2]),units = "secs")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接