将时间段扩展到定期发生的时间戳记

时间:2018-07-27 05:26:50

标签: r dplyr timestamp lubridate


不得不修改原始帖子以包含更好的示例

我对基于时间的数据有一个小标题,其中包含开始时间,结束时间和以下通用形式的类变量:

enter image description here

创建表格的代码:

library(lubridate)
st <- c(ymd_hms("2016-01-01 00:35:00"),
        ymd_hms("2016-01-01 00:39:00"),
        ymd_hms("2016-01-01 00:54:00"),
        ymd_hms("2016-01-01 00:56:00"),
        ymd_hms("2016-01-01 00:57:00"))

en <- c(ymd_hms("2016-01-01 00:36:00"),
        ymd_hms("2016-01-01 00:45:00"),
        ymd_hms("2016-01-01 00:55:00"),
        ymd_hms("2016-01-01 00:57:00"),
        ymd_hms("2016-01-01 00:58:00"))

cl <- c("a","a","a","b","b")

df <- tibble(st,en,cl)

时间段不一致,并且数据中存在一个隐藏的类:本质上,在此示例中,数据中未明确列出的时间属于第三类。

我需要一种方法来将此表扩展为具有常规句点(1分钟),以便可以将丢失的类分配给这些句点;目标是:

enter image description here

我确信这可以用dplyr和lubridate完成,但是已经能够完成。请记住,我的数据集非常庞大,因此最好采用无循环方法。

预先感谢

MR

2 个答案:

答案 0 :(得分:1)

尝试一下:

df_exp <- tibble(st = seq.POSIXt(from = min(st), to = max(st), by = "min"),
                 en = st + 60)
merge(df_exp, df, all = T)

首先,创建所有开始时间。结束时间是开始时间加1分钟。与包含类信息的数据框合并。顺便说一句:您的开始时间和结束时间确实重叠,这对于某些任务可能是个问题...

编辑以符合您的更新要求:

library(tidyr)
library(dplyr)
df_exp <- tibble(st = seq.POSIXt(from = min(st), to = max(en), by = "min"), en = st + 60)

# with tidyr 0.8
df_n <- df %>% 
  rowwise() %>% 
  mutate(st = list(as.character(seq.POSIXt(from = st, to = en, by = "min"))[-length(seq.POSIXt(from = st, to = en, by = "min"))])) %>% 
  unnest() %>% 
  select(-en) %>% 
  mutate(st = as.POSIXct(st))

df_exp %>% left_join(df_n)

# with tidyr 0.8.1 (untested)
df_n <- df %>% 
  rowwise() %>% 
  mutate(st = list(seq.POSIXt(from = st, to = en, by = "min")[-length(seq.POSIXt(from = st, to = en, by = "min"))])) %>% 
  unnest() %>% 
  select(-en)

df_exp %>% left_join(df_n)

答案 1 :(得分:0)

好的,我设法找到了一个解决方案,但这有点“循环”。我认为Tino的答案更好。对于有价值的东西,这是我的答案:

##################################################
#Regular period DF covering the entire period in the initial data
df_regular <- tibble(st = seq(min(df$st),max(df$en)-59,60),
                     en = st + 59)
##################################################
#Creates variable with number of 1-min periods per row in initial data
df$periods <- as.integer((df$en-df$st + 1)/60)

##################################################
#Scan each row
listDates <- list()
listClass <- list()

k <- 1
for (i in 1:nrow(df)) {
  for(j in 1:df$periods[i]) {
    listDates[k] <- c(df$st[i]+(j-1)*60)
    listClass[k] <- c(df$cl[i])

    k <- k+1
  }
}

#################################################
#create output table
df_out <- tibble(st = unlist(listDates) %>% as_datetime(),
                 cl = unlist(listClass)) %>%
  right_join(df_regular[1],by=c("st" ="st")) %>%
  mutate(en = st + 59) %>%
  select(st,en,cl)
#################################################

还结合了蒂诺关于避免日期重叠的建议。

干杯

MR