我有一个时间序列数据集,其中包含在不同采样位置('site_no')以不同频率测量的值。我想要对这个数据集进行过滤,以删除在短时间内连续采样的大量样本 - 在我这种情况下是在15分钟内。以下是一个简化的示例:
我想做的是,对于每个站点编号('site_no'),输出一个基于以下条件的新数据框:
- 选择每个站点编号的第一行(最早的日期/时间) - 从每个站点编号的第一行开始,向未来搜索15分钟; - 找到时间差值最大且小于等于15分钟的下一行; - 删除时间差值在此之间的任何行; - 对下一个时间步骤重复此过程;
例如,对于site_no为'1'的情况,第一个时间步骤是上午10:17。然后,我想删除10:19-10:29之间的时间值(第2-7行),并保留第8行,该行具有10:31上午的'date_time'时间戳。这是因为这个值是在15分钟窗口内与10:17上午的最大时间差。从10:31上午(第8行)开始,我想删除第9-14行(10:33-10:43上午),并选择第15行,该行具有10:45上午的时间戳-在10:31上午之后的14分钟(在15分钟窗口内的最大时间差)。
最后,如果行与前一行之间的时间差大于15分钟,我希望保留这两行。所以在这个例子中,我想保留每个site_no的最后一行,时间为上午5:00。
如果有可能以减少数据处理能力的方式实现这一点(即,使用向量化方法而不是显式循环),那将非常好,因为我的数据集非常大。
非常感谢您的帮助。
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),]
我想做的是,对于每个站点编号('site_no'),输出一个基于以下条件的新数据框:
- 选择每个站点编号的第一行(最早的日期/时间) - 从每个站点编号的第一行开始,向未来搜索15分钟; - 找到时间差值最大且小于等于15分钟的下一行; - 删除时间差值在此之间的任何行; - 对下一个时间步骤重复此过程;
例如,对于site_no为'1'的情况,第一个时间步骤是上午10:17。然后,我想删除10:19-10:29之间的时间值(第2-7行),并保留第8行,该行具有10:31上午的'date_time'时间戳。这是因为这个值是在15分钟窗口内与10:17上午的最大时间差。从10:31上午(第8行)开始,我想删除第9-14行(10:33-10:43上午),并选择第15行,该行具有10:45上午的时间戳-在10:31上午之后的14分钟(在15分钟窗口内的最大时间差)。
最后,如果行与前一行之间的时间差大于15分钟,我希望保留这两行。所以在这个例子中,我想保留每个site_no的最后一行,时间为上午5:00。
如果有可能以减少数据处理能力的方式实现这一点(即,使用向量化方法而不是显式循环),那将非常好,因为我的数据集非常大。
非常感谢您的帮助。
cumsum
或类似的函数)。我找不到一种方法可以在不使用Reduce(..)
或全宽度的frollapply
的情况下实现这一点。我怀疑你最好使用简单的循环(一次只处理一个site_no
),并使用向量化函数...这可能是最不低效的方法。另一种选择是使用类似runner
或slider
的软件包,它们可以根据时间跨度进行移动窗口操作,但是...它们并不总是更快,只是对你更方便。 - undefined