首页 > 解决方案 > 用多列中的时间测量时间体积

问题描述

我正在处理记录交互开始时间和结束时间的数据。我的目标是在特定的时间间隔(例如 12:00、12:30、13:00)测量音量。我的目标本质上是进行逻辑检查以查看时间范围(在本例中为一个小时块)是否适合由两列表示的时间范围。数据看起来像这样


client       start_time     end_time
smith          08:00          10:15
coven          09:30          10:25
peter          07:35          11:30


The result I would like would look like this

time         count
07:00          0
07:30          1
08:00          2
08:30          2
09:00          2
09:30          3
10:00          3
10:30          1
11:00          1
11:30          1

我知道我可以在 Excel 中手动完成,但有几千行,我希望它是可重现的。我用谷歌搜索了很多,我找不到答案。我希望有人能指出我正确的方向

我的第一个想法是通过使用 mutate 来构建非常宽的列。我将时间转换为整数,以使我更容易使用它们。这会起作用,但非常缓慢,最后我仍然需要找到一种方法来填补中间缺失的时间。

我曾想过使用within,但我不知道我是否可以在这里应用它。

这是代码。


library(tidyverse)

df1 <- df1 %>%
  mutate(eight_ = ifelse(start_num >= 480 & start_num <= 539 | end_num >= 480 & end_num <= 539 , 1, 0))

代码按预期工作,它将 1 放在正确的列中以表示开始和停止。问题是我不知道如何填写当前会收到零的中间列。

标签: rtime

解决方案


这是一个按间隔扩展start_time并计算结果的解决方案。end_time30 minute

library(tidyverse)
library(lubridate)

df <- tibble(
  client = c("smith", "coven", "peter"),
  start_time = c("08:00", "09:30", "07:35"),
  end_time = c("10:15", "10:25", "11:30")
)

df %>% 
  mutate(
    start_time = floor_date(as.POSIXct(start_time, format = '%H:%M', tz = 'UTC'), unit = '10 minutes'),
    end_time = floor_date(as.POSIXct(end_time, format = '%H:%M', tz = 'UTC'), unit = '10 minutes'),
  ) %>%
  nest(start_time, end_time) %>%
  mutate(time = map(data, ~seq(unique(.x$start_time), unique(.x$end_time), unit = 'min', by = '30 min'))) %>%
  unnest(time) %>% 
  mutate(time = format(time, '%H:%M')) %>% 
  group_by(time) %>% 
  tally()

# A tibble: 9 x 2
  time      n
  <chr> <int>
1 07:30     1
2 08:00     2
3 08:30     2
4 09:00     2
5 09:30     3
6 10:00     3
7 10:30     1
8 11:00     1
9 11:30     1

如果您需要完整的时间间隔,07:00 to 11:30您可以执行以下操作:

df %>%
  mutate(
    start_time = floor_date(as.POSIXct(start_time, format = "%H:%M", tz = "UTC"), unit = "10 minutes"),
    end_time = floor_date(as.POSIXct(end_time, format = "%H:%M", tz = "UTC"), unit = "10 minutes"),
  ) %>%
  nest(start_time, end_time) %>%
  mutate(time = map(data, ~ seq(unique(.x$start_time), unique(.x$end_time), unit = 'min', by = '30 min'))) %>%
  unnest(time) %>%
  mutate(time = format(time, "%H:%M")) %>%
  group_by(time) %>%
  tally() %>% 
  right_join( # add full sequence of time intervals
    tibble(time = seq(
      as.POSIXct("07:00", format = "%H:%M", tz = "UTC"),
      as.POSIXct("11:30", format = "%H:%M", tz = "UTC"), 
      unit = 'min', by = '30 min'
    )) %>%
      mutate(time = format(time, "%H:%M")),
    by = 'time'
  )

# A tibble: 10 x 2
   time      n
   <chr> <int>
 1 07:00    NA
 2 07:30     1
 3 08:00     2
 4 08:30     2
 5 09:00     2
 6 09:30     3
 7 10:00     3
 8 10:30     1
 9 11:00     1
10 11:30     1

推荐阅读