在不一致的时间序列数据集中过滤掉特定时间差内的值

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

我有时间序列数据集,其中包含在不同频率下测量的值。我想过滤这个数据集,以删除快速连续采集的大量样本 - 在我的例子中是在 15 分钟内。这是一个简化的示例:

library(lubridate)
set.seed(42)
n_sites <- 5
n_rows <- 100
df <- data.frame(
 Date_time = ymd_hms("2013-01-01 10:17:00", tz = "GMT") + minutes(0:(n_sites * n_rows - 1) * 2),
site_no = as.character(rep(1:n_sites, each = n_rows)),
 Value = rnorm(n_sites * n_rows))
df2 <- data.frame(Date_time = rep(ymd_hms("2013-01-02 05:00:00", tz = "GMT"),times=5),
              site_no = as.character(c(1:5)),
              Value = c(10,10,10,10,10))
df <- rbind(df,df2)
df <- df[order(df$site_no,df$Date_time),]

这些大多以 2 分钟为间隔。我想要做的,对于每个站点编号('site_no'),是根据以下内容输出一个新的数据框:

  • 选择每个站点的第一行(最早的日期/时间)_no
  • 从每个site_no的第一行开始搜索未来15分钟内的内容;
  • 识别出时间差值最大小于或等于15分钟的下一行;
  • 删除任何有时间差的行;
  • 在下一个时间步重复此过程;

例如,对于 site_no '1',第一个时间步长是上午 10:17。然后,我想删除上午 10:19-10:29(第 2-7 行)之间的时间值,并保留“date_time”时间戳为上午 10:31 的第 8 行。这是因为该值是 15 分钟窗口内距上午 10:17 的最大时间差。从上午 10:31(第 8 行)开始,我想删除第 9-14 行(上午 10:33-10:43)并选择时间戳为上午 10:45 - 上午 10:31 后 14 分钟(即15 分钟窗口内的最大时间差)。

最后,如果该行与前一行之间的时间差>15分钟,我想保留这两个。因此,在示例中,我想将每个 site_no 的最后一行保留在凌晨 5:00。

如果可以通过降低数据处理能力的方式实现这一点(即矢量化方法而不是显式循环),那就太好了,因为我有一个非常大的数据集。

提前非常感谢。

r dplyr time-series data.table lubridate
1个回答
0
投票

这是您要找的吗?

df %>% 
  group_by(site_no) %>% 
  mutate(timelevel = cut(Date_time, breaks = "15 mins")) %>% 
  group_by(site_no, timelevel) %>% 
  mutate(midt = min(Date_time),  madt = max(Date_time)) %>% 
  ungroup() %>% 
  filter(Date_time %in% c(midt, madt)) %>% 
  select(-c("midt", "madt"))

# A tibble: 145 × 4
   Date_time           site_no   Value timelevel          
   <dttm>              <chr>     <dbl> <fct>              
 1 2013-01-01 10:17:00 1        1.37   2013-01-01 10:17:00
 2 2013-01-01 10:31:00 1       -0.0947 2013-01-01 10:17:00
 3 2013-01-01 10:33:00 1        2.02   2013-01-01 10:32:00
 4 2013-01-01 10:45:00 1       -0.133  2013-01-01 10:32:00
 5 2013-01-01 10:47:00 1        0.636  2013-01-01 10:47:00
 6 2013-01-01 11:01:00 1       -0.172  2013-01-01 10:47:00
 7 2013-01-01 11:03:00 1        1.21   2013-01-01 11:02:00
 8 2013-01-01 11:15:00 1       -0.640  2013-01-01 11:02:00
 9 2013-01-01 11:17:00 1        0.455  2013-01-01 11:17:00
10 2013-01-01 11:31:00 1       -0.851  2013-01-01 11:17:00
# ℹ 135 more rows
# ℹ Use `print(n = ...)` to see more rows
© www.soinside.com 2019 - 2024. All rights reserved.