使用滚动平均值计算值窗口

时间:2020-01-09 19:30:47

标签: r rolling-computation rolling-average

我正在尝试计算15秒间隔内心率的滚动平均值。我有许多参与者的毫秒数据,因此毫秒值可能会重复多次,并且由于时间读数不一致,按行创建间隔是不可行的。

以下是一个参与者的一小部分数据样本。显然,另一位参与者的数据具有以不同时间间隔获取的不同毫秒数据。

理想的输出将包含一个新列,该列具有每个毫秒数据值的滚动平均值。

MS <- c(36148, 36753,37364,38062,38737,39580,40029,40387,41208,42006,42796, 43533,44274,44988,45696,46398,47079,47742,48429,49135,49861,50591,51324,52059)
HR <- c(84,84,84,84,84,96,84,84,96,84,84,96,84,84,96,84,84,84,84,84,84,84,84,84)

df <- data.frame(MS, HR)

我尝试了一些软件包(即Zoo的滚动功能套件),但在将其应用于此问题时遇到了困难。

谢谢!

4 个答案:

答案 0 :(得分:2)

Zoo中的

rollapplyr接受一个宽度向量,并且findInterval可用于计算15秒前MS中的索引,因此,如果我们从1:n中减去,我们得到{{ 1}},即平均职位数。问题中没有确切讨论产生哪个间隔,因此我们将假定每个间隔的右边缘在输入点处。

w

答案 1 :(得分:1)

data.table中使用非等价联接的选项,该选项还处理ID:

library(data.table)
setDT(df)[, avgHR := 
    df[.(ID=ID, start=MS-15000, end=MS), on=.(ID, MS>=start, MS<=end),
        by=.EACHI, mean(HR)]$V1
]

输出:

    ID    MS HR    avgHR
 1:  1 36148 84 84.00000
 2:  1 36753 84 84.00000
 3:  1 37364 84 84.00000
 4:  1 38062 84 84.00000
 5:  1 38737 84 84.00000
 6:  1 39580 96 86.00000
 7:  1 40029 84 85.71429
 8:  1 40387 84 85.50000
 9:  1 41208 96 86.66667
10:  1 42006 84 86.40000
11:  1 42796 84 86.18182
12:  1 43533 96 87.00000
13:  1 44274 84 86.76923
14:  1 44988 84 86.57143
15:  1 45696 96 87.20000
16:  1 46398 84 87.00000
17:  1 47079 84 86.82353
18:  1 47742 84 86.66667
19:  1 48429 84 86.52632
20:  1 49135 84 86.40000
21:  1 49861 84 86.28571
22:  1 50591 84 86.18182
23:  1 51324 84 86.18182
24:  1 52059 84 86.18182
    ID    MS HR    avgHR

数据:

MS <- c(36148, 36753,37364,38062,38737,39580,40029,40387,41208,42006,42796, 43533,44274,44988,45696,46398,47079,47742,48429,49135,49861,50591,51324,52059)
HR <- c(84,84,84,84,84,96,84,84,96,84,84,96,84,84,96,84,84,84,84,84,84,84,84,84)

df <- data.frame(ID=1, MS, HR)

答案 2 :(得分:0)

我不确定您要如何应用15s滚动平均值,但这是实现我认为您要寻找的内容的一种方法。首先我们对介于7.5s之前和7.5s之间的数据进行子集处理,然后取平均值。但是,这将产生边缘效应,因为在第一个值之前没有7.5s。

library(tidyverse)

roll_vec <- c()
for(i in 1:nrow(df)){
  ref <- df$MS[[i]]
  val <- df %>%
    filter(MS <= ref + 7500 & MS >= ref- 7500) %>%
    pull(HR) %>%
    mean
  roll_vec[[i]] <- val
}


df %>%
  mutate(roll_15s = roll_vec) 
#>       MS HR roll_15s
#> 1  36148 84 87.00000
#> 2  36753 84 87.00000
#> 3  37364 84 86.76923
#> 4  38062 84 86.57143
#> 5  38737 84 86.57143
#> 6  39580 96 86.57143
#> 7  40029 84 86.57143
#> 8  40387 84 86.57143
#> 9  41208 96 86.57143
#> 10 42006 84 86.57143
#> 11 42796 84 86.57143
#> 12 43533 96 86.57143
#> 13 44274 84 87.00000
#> 14 44988 84 87.27273
#> 15  4569 96 96.00000


df %>%
  mutate(roll_15s = roll_vec) %>%
  ggplot(aes(MS, HR))+
  geom_line()+
  geom_line(aes(y = roll_15s), color = "blue")

请注意,在图中,黑线是原始数据,蓝线是15s滚动平均值。

答案 3 :(得分:0)

一种可能的解决方案:

library(magrittr)
start_range <- df$MS[df$MS < max(df$MS)-15000]

lapply(start_range,function(t){
  data.frame(MS = mean(df$MS[df$MS %between% c(t,t+15000)]),
             HR = mean(df$HR[df$MS %between% c(t,t+15000)]))
}) %>% Reduce(rbind,.)

        MS       HR
1 43218.00 86.18182
2 43907.82 86.18182
3 44603.55 86.18182
4 44948.29 86.28571
5 45673.38 86.33333

我在您的数据中添加了一些要点(您提供的数据中只有两点):

MS <- c(36148, 36753,37364,38062,38737,39580,40029,40387,41208,42006,42796, 43533,44274,44988,45696,46398,47079,47742,48429,49135,49861,50591,51324,52059,53289,54424)
HR <- c(84,84,84,84,84,96,84,84,96,84,84,96,84,84,96,84,84,84,84,84,84,84,84,84,85,88)
df <- data.frame(MS, HR)

这里的想法是为每个MS值计算HR的均值和所有点之间的时间MS的时间t在15分钟后)。 我将其限制在我的值包含15s的范围内:start_range向量。