基于定义的时间间隔 (bin) 的时间序列平均值

Timeseries average based on a defined time interval (bin)

这是我的数据集的示例。我想每 10 秒根据时间(即 ts)计算 bin 平均值。能否请您提供一些提示,以便我继续?

在我的例子中,我想平均每 10 秒的时间 (ts) 和 Var。比如我会得到0到10秒的Var和ts的平均值;我将得到 Var 和 ts 从 11 到 20 秒等的另一个平均值

 df = data.frame(ts = seq(1,100,by=0.5), Var = runif(199,1, 10))

我可以使用 R 中的任何函数或库来完成这项任务吗?

有很多方法可以计算分箱平均值:使用基础 aggregateby,使用包 dplyrdata.table,可能使用 zoo 当然还有其他时间序列包...

library(dplyr)
df %>%
    group_by(interval = round(df$ts/10)*10) %>%
    summarize(Var_mean = mean(Var))
# A tibble: 11 x 2
   interval Var_mean
      <dbl>    <dbl>
 1        0 4.561653
 2       10 6.544980
 3       20 6.110336
 4       30 4.288523
 5       40 5.339249
 6       50 6.811147
 7       60 6.180795
 8       70 4.920476
 9       80 5.486937
10       90 5.284871
11      100 5.917074

这就是 dplyr 方法,看看它是如何实现的,data.table 让您命名中间变量,从而保持代码清晰易读。

总的来说,我同意@smci,dplyrdata.table 方法在这里是最好的。让我进一步详细说明。

# the dplyr way
library(dplyr)
df %>% 
  group_by(interval = ceiling(seq_along(ts)/20)) %>% 
  summarize(variable_mean = mean(Var))

# the data.table way
library(data.table)
dt <- data.table(df)
dt[,list(Var_mean = mean(Var)),
   by =  list(interval = ceiling(seq_along(dt$ts)/20))]

我不会在这里使用 tszooxts 等传统时间序列解决方案。他们的方法更适合处理常规频率和频率,如月度或季度数据。除了 ts 它们可以处理不规则频率和高频数据,但是许多方法(例如打印方法)效果不佳,或者至少不会给您带来优于 data.table 或 [=18= 的优势].

只要您只是聚合和分组 data.tabledplyr 就性能而言也可能更快。猜猜 data.table 在速度方面优于 dplyr,但你会有基准/配置文件,例如使用 microbenchmark。因此,如果您无论如何都不使用经典的 R 时间序列格式,则没有理由使用这些格式进行聚合。

假设问题中df,转换为动物园对象,然后聚合。

aggregate.zoo的第二个参数是一个向量,其长度与时间向量相同,给出了每个原始时间要映射到的新时间。第三个参数应用于时间已映射到相同值的所有时间序列值。这种映射可以通过多种方式完成,但在这里我们选择使用 10 * ceiling(time(z) / 10) 映射时间 (0, 10] 到 10,(10, 20] 到 20,等等)。

根据答案中的其他一些评论,让我指出,与使用数据框相比,这里有显着的简化,首先是因为数据已减少到一维(相对于 2 维) data.frame), 其次是因为它更有利于整体对象方法,而使用数据框需要不断地分离对象并在这些部分上工作,第三是因为现在拥有动物园的所有设施来操纵时间系列,如大量 NA 删除方案、滚动函数、重载算术运算符、n-way 合并、简单访问经典、点阵和 ggplot2 图形,design which emphasizes consistency with base R making it easy to learn and extensive documentation including 5 vignettes plus help files 有大量示例,考虑到 14 年的时间,错误可能很少开发和广泛使用。

library(zoo)
z <- read.zoo(df)

z10 <- aggregate(z, 10 * ceiling(time(z) / 10), mean)

给予:

> z10
      10       20       30       40       50       60       70       80 
5.629926 6.571754 5.519487 5.641534 5.309415 5.793066 4.890348 5.509859 
      90      100 
4.539044 5.480596 

(请注意,问题中的数据不可重现,因为它使用了没有 set.seed 的随机数,所以如果您尝试重复上述内容,您将不会得到相同的答案。)

现在我们可以绘制它,比如说,使用以下任何一种:

plot(z10)

library(lattice)
xyplot(z10)

library(ggplot2)
autoplot(z10)