在R中添加日期和时间值

在R中添加日期和时间值,r,R,我的数据文件中有以下类型的数据 DriveNo Date and Time 12 2017-01-31 23:00:00 //Start time of a trip for Driver12 134 2017-01-31 23:00:01 12 2017-01-31 23:10:00 //End time ( 10 min trip) 345 (some date/time) 12 2017-0

我的数据文件中有以下类型的数据

DriveNo     Date and Time
12         2017-01-31 23:00:00     //Start time of a trip for Driver12
134        2017-01-31 23:00:01
12         2017-01-31 23:10:00     //End time ( 10 min trip)
345        (some date/time)
12         2017-01-31 23:20:00     //Start Time 
12         2017-01-31 23:35:00     //End Time (15 min trip)
 .
 .
 .
数百万类似的数据随之而来

数据总数约为300万。现在,我需要得到每个驱动程序的时间驱动(大约有500个驱动程序)

DriveNo    TotalTimeDriven
12          35mins
134         ........(in days/hours/mins)
.
.
(也适用于所有其他驾驶员)

上面,DriveNo 12有四个条目,表示两次骑乘的开始和结束。是否有一种有效的R方法来实现这一点?

数据表解决方案:-

# Sample data    
df <- data.table(DriveNo = c(12, 134, 12, 134), Time = c("2017-01-31 23:00:00", "2017-01-31 23:00:01", "2017-01-31 23:10:00", "2017-01-31 23:20:01"))

df[, duration := max(as.POSIXct(Time)) - min(as.POSIXct(Time)), by = DriveNo]

df
DriveNo                Time duration
1:      12 2017-01-31 23:00:00  10 mins
2:     134 2017-01-31 23:00:01  20 mins
3:      12 2017-01-31 23:10:00  10 mins
4:     134 2017-01-31 23:20:01  20 mins
#示例数据
df数据表解决方案:-

# Sample data    
df <- data.table(DriveNo = c(12, 134, 12, 134), Time = c("2017-01-31 23:00:00", "2017-01-31 23:00:01", "2017-01-31 23:10:00", "2017-01-31 23:20:01"))

df[, duration := max(as.POSIXct(Time)) - min(as.POSIXct(Time)), by = DriveNo]

df
DriveNo                Time duration
1:      12 2017-01-31 23:00:00  10 mins
2:     134 2017-01-31 23:00:01  20 mins
3:      12 2017-01-31 23:10:00  10 mins
4:     134 2017-01-31 23:20:01  20 mins
#示例数据

df
range
返回最大值和最小值,并且
diff
减去向量中的序列号,因此您只需执行以下操作即可

aggregate(DateTime ~ DriveNo, df, function(x){diff(range(x))})
##   DriveNo DateTime
## 1      12      10 
## 2     134       0 
或者在dplyr中

library(dplyr)

df %>% group_by(DriveNo) %>% summarise(TimeDriven = diff(range(DateTime)))
## # A tibble: 2 × 2
##   DriveNo TimeDriven
##     <int>     <time>
## 1      12    10 mins
## 2     134     0 mins
要更改单位,直接调用
difftime
可能更简单


资料

使用循环布尔向量进行索引会更快,但在dplyr中,它们在某个点上会被取消分类。在data.table中

library(data.table)

setDT(df)[, .(TimeDriven = diff(range(DateTime))), by = DriveNo]
##    DriveNo TimeDriven
## 1:      12    10 mins
## 2:     134     0 mins
库(data.table)
种子(47)
驾驶1:1 60分钟
#>2:2110分钟
#>3:3120分钟
#>4:4130分钟
#>5:580分钟
或者在基地,

set.seed(47)
驱动器1 160
#> 2       2     110 
#> 3       3     120 
#> 4       4     130 
#> 5       5      80

如果驾驶员的驾驶次数为奇数,则所有表格都可能出现问题,这在给定的假设下是不可能的。如果是,则需要进行更多清理。

range
返回最大值和最小值,并且
diff
减去向量中的序列号,因此您只需执行以下操作即可

aggregate(DateTime ~ DriveNo, df, function(x){diff(range(x))})
##   DriveNo DateTime
## 1      12      10 
## 2     134       0 
或者在dplyr中

library(dplyr)

df %>% group_by(DriveNo) %>% summarise(TimeDriven = diff(range(DateTime)))
## # A tibble: 2 × 2
##   DriveNo TimeDriven
##     <int>     <time>
## 1      12    10 mins
## 2     134     0 mins
要更改单位,直接调用
difftime
可能更简单


资料

使用循环布尔向量进行索引会更快,但在dplyr中,它们在某个点上会被取消分类。在data.table中

library(data.table)

setDT(df)[, .(TimeDriven = diff(range(DateTime))), by = DriveNo]
##    DriveNo TimeDriven
## 1:      12    10 mins
## 2:     134     0 mins
库(data.table)
种子(47)
驾驶1:1 60分钟
#>2:2110分钟
#>3:3120分钟
#>4:4130分钟
#>5:580分钟
或者在基地,

set.seed(47)
驱动器1 160
#> 2       2     110 
#> 3       3     120 
#> 4       4     130 
#> 5       5      80

如果驾驶员的驾驶次数为奇数,则所有表格都可能出现问题,这在给定的假设下是不可能的。如果是,则需要进行更多清洁。

DriveNo
分组,然后取
diff(range(DateTime))
。在dplyr中,
df%>%groupby(DriveNo)%%>%summary(TimeDriven=diff(range(DateTime))
,不过
aggregate
或data.table也可以正常工作。groupby
DriveNo
,然后使用
diff(range(DateTime))
。在dplyr中,
df%>%group_by(DriveNo)%%>%summary(TimeDriven=diff(range(DateTime))
,尽管
aggregate
或data.table也可以正常工作。您也可以交替地执行
DT[order(time)、difftime(time[1]、time[2]、units=“min”)、by=g
或类似操作。@Frank只有在有两次的情况下才有效@啊,很可能折叠组更有意义:
df[,Time:=as.POSIXct(Time)][,(duration=max(Time)-min(Time)),by=DriveNo]
@alistaire是的,我同意正在折叠,但没有理由相信数据应该有两个以上的条目。当然,我见过这样的数据集,它们有1-2个条目。对于更多条目的情况,由于
?GForce
中提到的内容,在计算方式方面(或交替使用min和max,而不是排序),比
DT[order(t),(first(t),last(t)),by=g][,diff:=V2-V1]
有一些效率的提高。您可以交替使用
DT[order(time),difftime(time[1],time[2],units=“min”),by=g]
或类似的方法。@只有在有两次的情况下才有效@啊,很可能折叠组更有意义:
df[,Time:=as.POSIXct(Time)][,(duration=max(Time)-min(Time)),by=DriveNo]
@alistaire是的,我同意正在折叠,但没有理由相信数据应该有两个以上的条目。当然,我见过这样的数据集,它们有1-2个条目。对于更多条目的情况,在计算方式方面(或交替使用最小值和最大值,而不是排序),从
DT[顺序(t),(第一(t),最后(t)),by=g][,diff:=V2-V1]
可以提高效率多亏了
?GForce
中提到的内容。小结:在行程不完整的情况下,可能需要一些其他值,而不是零。。。NA(属于difftime类)或基于数据提取时间的时间差。@alistaire df%%>%group_by(DriveNo)%%>%Summary(TimeDriven=diff(range(DateTime)))将仅向我提供第一个和最后一个条目(range)的时间驱动。但是,对于同一驱动程序,数据集有多个条目。正如我在问题中提到的,只有500个驱动程序,但数据约为300万。您的示例结果意味着您应该为每个驱动程序创建一行。有些时间戳是开始的,有些是停止的?如果是,它们是如何区分的?位置?听上去,你需要编辑你的例子,使之成为一个足够有代表性的子集,这显然是现在没有的。@alistaire是的,我会为每个驱动程序编一行。对于start/stop,驾驶员1的第一个条目是start,第二个条目是stop。第三个条目是重新开始,第四个条目是停止,依此类推。。因此,如果第一个和第二个相差10分钟,第三个和第四个相差15分钟,那么我的结果值应该是25。你需要用足够的数据和相应的期望结果来编辑你的问题。小结:在行程不完整的情况下,可能需要一些其他值,而不是零。。。NA(属于difftime类)或基于数据提取时间的时间差。