我有时间序列数据集,其中包含在不同频率下测量的值。我想过滤这个数据集,以删除快速连续采集的大量样本 - 在我的例子中是在 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'),是根据以下内容输出一个新的数据框:
例如,对于 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。
如果可以通过降低数据处理能力的方式实现这一点(即矢量化方法而不是显式循环),那就太好了,因为我有一个非常大的数据集。
提前非常感谢。
这是您要找的吗?
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