【问题标题】:adding columns based on ordering and grouping基于排序和分组添加列
【发布时间】:2016-09-26 23:24:08
【问题描述】:

我有这个数据框

dat = data.frame(ID= c(1,1,1,2,3,3),
              NumberInSequence= c(1,2,3,1,1,2),
              StartTime = as.POSIXct(c("2016-01-01 05:52:05 GMT","2016-01-01 05:52:11 GMT","2016-01-01 05:52:16 GMT","2016-01-01 05:40:05 GMT","2016-01-01 06:12:13 GMT","2016-01-01 07:12:26 GMT"))  ,
              EndTime = as.POSIXct(c("2016-01-01 05:52:10 GMT","2016-01-01 05:52:16 GMT","2016-01-01 05:52:30 GMT","2016-01-01 05:46:05 GMT","2016-01-01 06:12:25 GMT","2016-01-01 08:00:00 GMT")  )
               )


dat

  ID NumberInSequence           StartTime             EndTime
1  1                1 2016-01-01 05:52:05 2016-01-01 05:52:10
2  1                2 2016-01-01 05:52:11 2016-01-01 05:52:16
3  1                3 2016-01-01 05:52:16 2016-01-01 05:52:30
4  2                1 2016-01-01 05:40:05 2016-01-01 05:46:05
5  3                1 2016-01-01 06:12:13 2016-01-01 06:12:25
6  3                2 2016-01-01 07:12:26 2016-01-01 08:00:00

每个 ID 可以有 1 行或多行,并且每个 ID 的每一行都按时间顺序排列。我想添加 2 列:

第 1 列:“Duration”,即从 ID 的 EndTime 到同一 ID 的下一个开始时间之间的时间长度,以秒为单位。

第2列:“下次开始时间”,即同一ID的实际下次开始时间。

所以结果应该是这样的:

dat$Duration = ?

dat$NextStartTime = ?

  ID NumberInSequence           StartTime             EndTime   Duration    NextStartTime
1  1                1 2016-01-01 05:52:05 2016-01-01 05:52:10     1     2016-01-01 05:52:11
2  1                2 2016-01-01 05:52:11 2016-01-01 05:52:16     0     2016-01-01 05:52:16
3  1                3 2016-01-01 05:52:16 2016-01-01 05:52:30     NA     NA
4  2                1 2016-01-01 05:40:05 2016-01-01 05:46:05     NA     NA
5  3                1 2016-01-01 06:12:13 2016-01-01 06:12:25     3601    2016-01-01 07:12:26
6  3                2 2016-01-01 07:12:26 2016-01-01 08:00:00     NA     NA

例如,对于 ID = 3 的 NUMBER IN SEQUENCE = 1,结束时间是 61 秒后,因此持续时间是 61,下一个开始时间是从 ID = 3 开始的 07:12:26,并且序列中的数字 = 2。

对于没有下一个开始时间的行,NA 应显示为 ID = 2 和序列号 = 1。

我正在考虑以某种方式使用 dplyr 进行此操作....

######## 更新

lead() 是答案,但有一个小问题。请看这篇文章

using dplyr lead but with some contraints

【问题讨论】:

  • dat %>% group_by(ID) %>% mutate(NextStartTime = lead(StartTime), duration = difftime(NextStartTime, EndTime, units = 's')) 也许

标签: r dplyr


【解决方案1】:

对于NextStartTime,只要您的数据有序(如果不确定,请使用arrange(ID, NumberInSequence)),您可以使用dplyr::lead,这就像在具有负滞后的时间序列上使用stats::lag

对于Duration,您可以减去时间,但如果单位可以使用不同的量级单位,则直接使用difftime 会更安全,这样您可以保持单位一致。

大家一起:

library(dplyr)

dat %>% group_by(ID) %>% 
    arrange(ID, NumberInSequence) %>%    # not necessary if already arranged, as here
    mutate(NextStartTime = lead(StartTime), 
           Duration = difftime(NextStartTime, EndTime, units = 's'))

## Source: local data frame [6 x 6]
## Groups: ID [3]
## 
##      ID NumberInSequence           StartTime             EndTime       NextStartTime  Duration
##   <dbl>            <dbl>              <dttm>              <dttm>              <dttm>    <time>
## 1     1                1 2016-01-01 05:52:05 2016-01-01 05:52:10 2016-01-01 05:52:11    1 secs
## 2     1                2 2016-01-01 05:52:11 2016-01-01 05:52:16 2016-01-01 05:52:16    0 secs
## 3     1                3 2016-01-01 05:52:16 2016-01-01 05:52:30                <NA>   NA secs
## 4     2                1 2016-01-01 05:40:05 2016-01-01 05:46:05                <NA>   NA secs
## 5     3                1 2016-01-01 06:12:13 2016-01-01 06:12:25 2016-01-01 07:12:26 3601 secs
## 6     3                2 2016-01-01 07:12:26 2016-01-01 08:00:00                <NA>   NA secs

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-08-02
  • 2020-10-15
  • 2021-11-08
  • 2015-04-13
  • 1970-01-01
  • 2011-12-04
  • 2021-12-23
  • 2014-09-02
相关资源
最近更新 更多