在R中的每个组中创建数字时间格式的时间间隔周期

8fq7wneg  于 2022-12-24  发布在  其他
关注(0)|答案(2)|浏览(156)

我想为每个组创建一个时间间隔周期,我的时间格式是数字格式。假设我想从第一条记录开始间隔1小时,在1小时内的每条记录都将是interval 1,从第一条记录开始间隔1小时后小于2小时的任何记录都将是interval 2,依此类推(对于每个user组)。
从技术上讲,我正在寻找创建一个小时的垃圾箱从一开始。

  1. df<-read.table(text="
  2. user timestart
  3. 1 1421286975
  4. 1 1421287343
  5. 1 1421470513
  6. 1 1421470513
  7. 1 1421471816
  8. 1 1421806839
  9. 2 1424217068
  10. 2 1424217150
  11. 2 1424218395",header=T,stringsAsFactors = F)
  12. # result: (might not 100% accurate but you get the point)
  13. user timestart interval_1h
  14. 1 1421286975 1
  15. 1 1421287343 1
  16. 1 1421470513 2
  17. 1 1421470513 2
  18. 1 1421471816 2
  19. 1 1421806839 3
  20. 2 1424217068 1
  21. 2 1424217150 1
  22. 2 1424218395 1
9udxz4iz

9udxz4iz1#

对我来说,这个问题有两种解释,下面是两种解释的解决方案,我们使用dplyr来获得想要的输出:
1.第一种解释创建了一个输出,该输出类似于所显示的输出,但与您的实际问题相矛盾:

  1. df %>%
  2. mutate(time = as.POSIXlt(timestart, origin = "1970-01-01")) %>%
  3. group_by(user) %>%
  4. mutate(grp = cumsum(coalesce(difftime(time, lag(time), units = "hours") >= 1, TRUE))) %>%
  5. group_by(user, grp) %>%
  6. mutate(grp2 = difftime(time, first(time), units = "hours") >= 1) %>%
  7. group_by(user) %>%
  8. mutate(grp = grp + cumsum(grp2), .keep = "unused") %>%
  9. ungroup()

这将返回

  1. # A tibble: 10 x 4
  2. user timestart time grp
  3. <int> <int> <dttm> <int>
  4. 1 1 1421286975 2015-01-15 02:56:15 1
  5. 2 1 1421287343 2015-01-15 03:02:23 1
  6. 3 1 1421470513 2015-01-17 05:55:13 2
  7. 4 1 1421470513 2015-01-17 05:55:13 2
  8. 5 1 1421471816 2015-01-17 06:16:56 2
  9. 6 1 1421475400 2015-01-17 07:16:40 3
  10. 7 1 1421806839 2015-01-21 03:20:39 4
  11. 8 2 1424217068 2015-02-18 00:51:08 1
  12. 9 2 1424217150 2015-02-18 00:52:30 1
  13. 10 2 1424218395 2015-02-18 01:13:15 1

1.第二个方法获取每个用户的第一个timestart,并创建1小时的时隙,每个后续时间戳被分配给其中一个时隙,并基于这些时隙创建组。

  1. df %>%
  2. group_by(user) %>%
  3. mutate(time = as.POSIXlt(timestart, origin = "1970-01-01"),
  4. helper = (timestart %% first(timestart)) %/% 3600,
  5. grp = cumsum(helper - lag(helper, default = 0) > 0) + 1) %>%
  6. ungroup() %>%
  7. select(-helper)

这只回来了

  1. # A tibble: 10 x 4
  2. user timestart time grp
  3. <int> <int> <dttm> <dbl>
  4. 1 1 1421286975 2015-01-15 02:56:15 1
  5. 2 1 1421287343 2015-01-15 03:02:23 1
  6. 3 1 1421470513 2015-01-17 05:55:13 2
  7. 4 1 1421470513 2015-01-17 05:55:13 2
  8. 5 1 1421471816 2015-01-17 06:16:56 3
  9. 6 1 1421475400 2015-01-17 07:16:40 4
  10. 7 1 1421806839 2015-01-21 03:20:39 5
  11. 8 2 1424217068 2015-02-18 00:51:08 1
  12. 9 2 1424217150 2015-02-18 00:52:30 1
  13. 10 2 1424218395 2015-02-18 01:13:15 1

数据

我添加了一个数据点以获得更好的示例数据

  1. df <- structure(list(user = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L
  2. ), timestart = c(1421286975L, 1421287343L, 1421470513L, 1421470513L,
  3. 1421471816L, 1421475400L, 1421806839L, 1424217068L, 1424217150L,
  4. 1424218395L)), class = "data.frame", row.names = c(NA, -10L))
展开查看全部
t9aqgxwy

t9aqgxwy2#

考虑一些具有对ave的多次调用的helper列:

  1. output <- within(
  2. df, {
  3. timedt <- as.POSIXct(timestart, origin="1970-01-01")
  4. first <- ave(timedt, user, FUN=min)
  5. hour_diff <- round(as.numeric(difftime(timedt, first, unit="hours")))
  6. interval_1h <- ave(
  7. ifelse(ave(hour_diff, user, hour_diff, FUN=seq_along) == 1, 1, 0),
  8. user,
  9. FUN=cumsum
  10. )
  11. rm(timedt, first, hour_diff)
  12. }
  13. )
  14. output
  15. user timestart interval_1h
  16. 1 1 1421286975 1
  17. 2 1 1421287343 1
  18. 3 1 1421470513 2
  19. 4 1 1421470513 2
  20. 5 1 1421471816 2
  21. 6 1 1421806839 3
  22. 7 2 1424217068 1
  23. 8 2 1424217150 1
  24. 9 2 1424218395 1
展开查看全部

相关问题