基于定义的时间间隔 (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 中的任何函数或库来完成这项任务吗?
有很多方法可以计算分箱平均值:使用基础 aggregate
、by
,使用包 dplyr
、data.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,dplyr
和data.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))]
我不会在这里使用 ts
、zoo
或 xts
等传统时间序列解决方案。他们的方法更适合处理常规频率和频率,如月度或季度数据。除了 ts
它们可以处理不规则频率和高频数据,但是许多方法(例如打印方法)效果不佳,或者至少不会给您带来优于 data.table
或 [=18= 的优势].
只要您只是聚合和分组 data.table
和 dplyr
就性能而言也可能更快。猜猜 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)
这是我的数据集的示例。我想每 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 中的任何函数或库来完成这项任务吗?
有很多方法可以计算分箱平均值:使用基础 aggregate
、by
,使用包 dplyr
、data.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,dplyr
和data.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))]
我不会在这里使用 ts
、zoo
或 xts
等传统时间序列解决方案。他们的方法更适合处理常规频率和频率,如月度或季度数据。除了 ts
它们可以处理不规则频率和高频数据,但是许多方法(例如打印方法)效果不佳,或者至少不会给您带来优于 data.table
或 [=18= 的优势].
只要您只是聚合和分组 data.table
和 dplyr
就性能而言也可能更快。猜猜 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)