这个问题与我在以下链接中的帖子密切相关:Expand periods to regularly occuring timestamps
从本质上讲,这是该问题的反向步骤。
我现在有一个规则间隔的数据集(1分钟周期),我需要折叠句点,以便每行代表一个时间段,其中类保持不变,如下所示:
样本输入数据框是:
df_in <- tibble(st =seq(ymd_hms("2016-01-01 00:35:00"),
ymd_hms("2016-01-01 00:58:00")-60,60),
en = st+59)
df_in$cl <- c("a",rep("c",3),rep("a",6),rep("c",9),rep("a",1),"c",rep("b",2))
我设法通过循环实现这一点,如下面的代码所示,但这是非常低效和慢(我的数据源是数百万行)。我确信有一种通过dplyr进行验证的方法,我希望有人可以指出我正确的方向:
df_in$flag <- 1
df_in %>%
mutate(flag = ifelse(lag(cl)==cl,0,1)) -> df_in
df_in$flag[1] <- 1
df_in$flag2 <- 0
df_in$flag2[1] <- 1
for (i in 2:nrow(df_in)) {
if (df_in$flag[i] == 0) {
df_in$flag2[i] = df_in$flag2[i-1]
} else {
df_in$flag2[i] = df_in$flag2[i-1] + 1
}
}
df_in %>%
group_by(flag2) %>%
summarise(st = min(st),
en = max(en),
cl = unique(cl)) %>%
View()
再次感谢...
这是使用data.table
的一个选项
library(data.table)
setDT(df_in)[, .(st = min(st), en = max(en)), by = .(cl, idx = rleid(cl))]
# cl idx st en
#1: a 1 2016-01-01 00:35:00 2016-01-01 00:35:59
#2: c 2 2016-01-01 00:36:00 2016-01-01 00:38:59
#3: a 3 2016-01-01 00:39:00 2016-01-01 00:44:59
#4: c 4 2016-01-01 00:45:00 2016-01-01 00:53:59
#5: a 5 2016-01-01 00:54:00 2016-01-01 00:54:59
#6: c 6 2016-01-01 00:55:00 2016-01-01 00:55:59
#7: b 7 2016-01-01 00:56:00 2016-01-01 00:57:59
我们通过st
和min(st)
将en
设置为等于max(en)
和cl
等于idx = rleid(cl)
。 rleid
创建了一个“游程长度类型id列”。
有了dplyr
,你可以做到
library(dplyr)
df_in %>%
mutate(idx = data.table::rleid(cl)) %>%
group_by(cl, idx) %>%
summarise(st = min(st),
en = max(en)) %>%
arrange(idx) %>%
select(-idx)