将周期扩展为定期出现的时间戳
Expand periods to regularly occuring timestamps
必须修改原始 post 以包含更好的示例
我有一个基于时间的数据,包含开始时间、结束时间和以下一般形式的 class 变量:
制作table的代码:
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)
周期不一致,数据中隐藏了class:本质上,数据中未明确列出的时间属于本例中的第三个class。
我需要一种方法来扩展此 table 以具有固定的周期(1 分钟),以便我可以将缺失的 class 分配给这些周期;目标是:
我相信这可以用 dplyr 和 lubridate 来完成,但还没有能够完成。请记住,我的数据集很大,所以最好采用非循环方法。
提前致谢,
先生
试试这个:
df_exp <- tibble(st = seq.POSIXt(from = min(st), to = max(st), by = "min"),
en = st + 60)
merge(df_exp, df, all = T)
首先,创建所有开始时间。结束时间就是开始时间加 1 分钟。与包含 class 信息的数据框合并。顺便说一句:您的开始和结束时间确实重叠,这对于某些任务来说可能是个问题...
编辑以符合您更新后的要求:
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)
好的,我设法找到了解决方案,但有点偏向 "loopy"。我认为蒂诺的回答更好。对于什么是值得的,这是我的答案:
##################################################
#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)
#################################################
还采纳了 Tino 关于避免日期重叠的建议。
干杯,
先生
必须修改原始 post 以包含更好的示例
我有一个基于时间的数据,包含开始时间、结束时间和以下一般形式的 class 变量:
制作table的代码:
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)
周期不一致,数据中隐藏了class:本质上,数据中未明确列出的时间属于本例中的第三个class。
我需要一种方法来扩展此 table 以具有固定的周期(1 分钟),以便我可以将缺失的 class 分配给这些周期;目标是:
我相信这可以用 dplyr 和 lubridate 来完成,但还没有能够完成。请记住,我的数据集很大,所以最好采用非循环方法。
提前致谢,
先生
试试这个:
df_exp <- tibble(st = seq.POSIXt(from = min(st), to = max(st), by = "min"),
en = st + 60)
merge(df_exp, df, all = T)
首先,创建所有开始时间。结束时间就是开始时间加 1 分钟。与包含 class 信息的数据框合并。顺便说一句:您的开始和结束时间确实重叠,这对于某些任务来说可能是个问题...
编辑以符合您更新后的要求:
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)
好的,我设法找到了解决方案,但有点偏向 "loopy"。我认为蒂诺的回答更好。对于什么是值得的,这是我的答案:
##################################################
#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)
#################################################
还采纳了 Tino 关于避免日期重叠的建议。
干杯,
先生