根据课程保持时间顺序折叠常规时间段数据

问题描述 投票:0回答:1

这个问题与我在以下链接中的帖子密切相关:Expand periods to regularly occuring timestamps

从本质上讲,这是该问题的反向步骤。

我现在有一个规则间隔的数据集(1分钟周期),我需要折叠句点,以便每行代表一个时间段,其中类保持不变,如下所示:

enter image description here

样本输入数据框是:

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()

再次感谢...

r dplyr timestamp vectorization
1个回答
1
投票

这是使用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

我们通过stmin(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)
© www.soinside.com 2019 - 2024. All rights reserved.