R中的日期时间差异

DateTime Diff in R

如果一条记录显示 diff 每个用户 7 天,我需要帮助创建一个将记录分类为 TRUE 的函数。请注意,UserDateTime 字段没有按顺序排列,我只是为了更容易表示数据集而排列它。

 User     DateTime              Result
 A        2015-05-27 17:13      FALSE
 A        2015-06-23 14:17      FALSE
 A        2015-06-24 15:44      TRUE
 A        2015-06-27 12:16      TRUE
 B        2015-03-04 18:07      FALSE
 C        2015-07-27 08:26      FALSE
 D        2015-03-26 18:13      FALSE
 D        2015-05-20 10:35      FALSE
 D        2015-05-25 18:07      TRUE

显然,当我尝试这个时我的函数不起作用,因为它只给了我一个逻辑值:

 repeatfun <- function(x) {ifelse(sum(diff(x) < 7), TRUE, FALSE)}

以下是便于复制的数据:

User <- c('A', 'A', 'A', 'A', 'A', 'B', 'C', 'D', 'D', 'D', 'D', 'D')
DateTime <- c('2015-05-27', '2015-06-23', '2015-06-24', '2015-06-27', '2015-07-08',
          '2015-03-04', '2015-07-27',
          '2015-03-26', '2015-05-20', '2015-05-25', '2015-06-17', '2015-08-13')
df <- as.data.frame(cbind(User, DateTime))
df$DateTime <- as.Date(df$DateTime)

使用dplyr,我们可以按User分组,从最早的日期开始排列DateTime。最后创建ResultDateTime是从前一个日期减去的。参数 default=FALSE 阻止 NA 值出现。使用 (x < 7) 测试输出。

library(dplyr)
df %>% group_by(User) %>% arrange(DateTime) %>% 
  mutate(Result=DateTime-lag(DateTime, default=F) < 7)
# Source: local data frame [9 x 3]
# Groups: User [4]
# 
#     User   DateTime Result
#   (fctr)     (date)  (lgl)
# 1      A 2015-05-27  FALSE
# 2      A 2015-06-23  FALSE
# 3      A 2015-06-24   TRUE
# 4      A 2015-06-27   TRUE
# 5      B 2015-03-04  FALSE
# 6      C 2015-07-27  FALSE
# 7      D 2015-03-26  FALSE
# 8      D 2015-05-20  FALSE
# 9      D 2015-05-25   TRUE

另一种解决方案使用 data.table 和您稍作改动的函数:

#your function without the sum function
repeatfun <- function(x) {ifelse(diff(x) < 7, TRUE, FALSE)}

#data.table solution
setDT(df)[, ,key='DateTime'][, Result := c(FALSE, repeatfun(DateTime)), by=User]

输出:

> df
   User   DateTime Result
1:    A 2015-05-27  FALSE
2:    A 2015-06-23  FALSE
3:    A 2015-06-24   TRUE
4:    A 2015-06-27   TRUE
5:    B 2015-03-04  FALSE
6:    C 2015-07-27  FALSE
7:    D 2015-03-26  FALSE
8:    D 2015-05-20  FALSE
9:    D 2015-05-25   TRUE