我正在 Shiny 中开发一个简单的时间表/时间跟踪应用程序,供个人使用。该应用程序将记录我开始和停止事件的时间戳。然而,一天中的某些时候,特定任务之间存在自然间隙,但您仍然需要做一些事情。这些中间时间段不会被应用程序捕获,而是作为时间戳之间的“间隙”出现在数据中。示例数据如下所示(帖子末尾的数据输出):
# A tibble: 9 x 3
start end activity
<dttm> <dttm> <chr>
1 2022-11-28 10:00:00 2022-11-28 10:50:30 Activity 1
2 2022-11-28 10:50:30 2022-11-28 11:39:05 Activity 2
3 2022-11-28 12:01:00 2022-11-28 16:10:45 Activity 2
4 2022-11-29 10:00:00 2022-11-29 10:50:30 Activity 1
5 2022-11-29 10:50:31 2022-11-29 11:00:15 Activity 4
6 2022-11-29 12:00:00 2022-11-29 13:00:00 Activity 5
7 2022-11-29 13:00:00 2022-11-29 16:00:00 Activity 2
8 2022-11-30 08:00:05 2022-11-30 10:00:00 Activity 1
9 2022-11-30 16:03:05 2022-11-30 17:00:00 Activity 2
数据上的差距是显而易见的。例如,28 日,第一个条目和第二个条目之间没有间隙(第一个条目的结束时间等于第二个条目的开始时间)。然而,第二条目和第三条目之间存在间隙(第二条目的结束时间与第三条目不同)。我们可以在样本数据中找到其他日期的类似差距。
我想要做的是用名为“其他”的事件来填补这些空白,这样每天第一个条目的开始和最后一个条目的结束之间就没有间隙。也就是说,所有现有的空白都被填充。所需的输出如下所示:
# A tibble: 13 x 3
start end activity
<dttm> <dttm> <chr>
1 2022-11-28 10:00:00 2022-11-28 10:50:30 Activity 1
2 2022-11-28 10:50:30 2022-11-28 11:39:05 Activity 2
3 2022-11-28 11:39:05 2022-11-28 12:01:00 Other
4 2022-11-28 12:01:00 2022-11-28 16:10:45 Activity 2
5 2022-11-29 10:00:00 2022-11-29 10:50:30 Activity 1
6 2022-11-29 10:50:30 2022-11-29 10:50:31 Other
7 2022-11-29 10:50:31 2022-11-29 11:00:15 Activity 4
8 2022-11-29 11:00:15 2022-11-29 12:00:00 Other
9 2022-11-29 12:00:00 2022-11-29 13:00:00 Activity 5
10 2022-11-29 13:00:00 2022-11-29 16:00:00 Activity 2
11 2022-11-30 08:00:05 2022-11-30 10:00:00 Activity 1
12 2022-11-30 10:00:00 2022-11-30 16:03:05 Other
13 2022-11-30 16:03:05 2022-11-30 17:00:00 Activity 2
在可预见的 future ,数据将每天创建,因此该解决方案可能必须适用于更大的数据集,并且最好采用矢量化方法。到目前为止,我一直在 tidyverse 和 lubridate 中工作。我不确定是否有一些简单/容易的事情被我忽略了(我希望如此)。
我首先想到的是写一个循环或者使用lapply类型表达式。随着数据的增长,这会很快失控,除非我记得始终填写或运行检查并定期填写数据(我可能最终会到达应用程序的这一部分)。
或者,我开始考虑将数据旋转更长的时间,创建 2 场比赛的组,并指定每天的开始和结束时间,以找出差距。这可能很快,但我很难找到解决问题的好方法。
如果重要的话,每次添加条目时数据都会提交到本地 SQLite 数据库。
非常感谢对此的任何帮助/意见。
示例数据:
library(tidyverse)
library(lubridate)
db <- structure(list(start = structure(c(1669629600, 1669632630, 1669636860,
1669716000, 1669719031, 1669723200, 1669726800, 1669795205, 1669824185
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), end = structure(c(1669632630,
1669635545, 1669651845, 1669719030, 1669719615, 1669726800, 1669737600,
1669802400, 1669827600), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
activity = c("Activity 1", "Activity 2", "Activity 2", "Activity 1",
"Activity 4", "Activity 5", "Activity 2", "Activity 1", "Activity 2"
)), row.names = c(NA, -9L), class = c("tbl_df", "tbl", "data.frame"
))
最佳答案
这里有一种方法:
library(dplyr)
library(lubridate)
db %>%
bind_rows(
data.frame(
start = db %>%
group_by(day(start)) %>%
filter(end != lead(start)) %>%
pull(end),
end = NA,
activity= "Other"
)
) %>%
arrange(start) %>%
mutate(end = if_else(is.na(end),lead(start),end))
# A tibble: 13 x 3
start end activity
<dttm> <dttm> <chr>
1 2022-11-28 10:00:00 2022-11-28 10:50:30 Activity 1
2 2022-11-28 10:50:30 2022-11-28 11:39:05 Activity 2
3 2022-11-28 11:39:05 2022-11-28 12:01:00 Other
4 2022-11-28 12:01:00 2022-11-28 16:10:45 Activity 2
5 2022-11-29 10:00:00 2022-11-29 10:50:30 Activity 1
6 2022-11-29 10:50:30 2022-11-29 10:50:31 Other
7 2022-11-29 10:50:31 2022-11-29 11:00:15 Activity 4
8 2022-11-29 11:00:15 2022-11-29 12:00:00 Other
9 2022-11-29 12:00:00 2022-11-29 13:00:00 Activity 5
10 2022-11-29 13:00:00 2022-11-29 16:00:00 Activity 2
11 2022-11-30 08:00:05 2022-11-30 10:00:00 Activity 1
12 2022-11-30 10:00:00 2022-11-30 16:03:05 Other
13 2022-11-30 16:03:05 2022-11-30 17:00:00 Activity 2
关于r - 填充不规则结束和开始时间戳之间的间隙,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74643676/