计算 R 中指定条件之前 30 秒的平均值

Calculate average of values 30 seconds prior to a specified condition in R

我有海豹的一系列潜水数据。我想计算潜水开始前 30 秒内海豹的心率。但是,我不确定如何告诉 R,如果遇到潜水开始,从该开始时间返回 30 秒并计算平均心率。我假设它需要是一个循环,条件是如果该行包含潜水开始,然后返回并在该开始前的最后 30 秒取平均值。

我真的希望这是可能的,我很难想象用我的数据计算这些信息的任何其他方法。

我的数据看起来像这样,潜水开始前有 NA 潜水信息,然后是潜水数据开始的潜水开始时间。数据帧中有多次潜水,在潜水之间可能有几分钟的时间它们悬挂在数据为 NA 的表面。但我只对计算潜水开始前 30 秒的心率感兴趣,而不是潜水之间的全部时间。注意:在用时间计算事物时,我倾向于使用纪元时间,因为这样更容易与 R 通信。

          HR      epoch            datetime diveNum dive_start
1  103.44828 1523026041 2018-04-06 14:47:21      NA         NA
2   82.19178 1523026041 2018-04-06 14:47:21      NA         NA
3   88.23529 1523026042 2018-04-06 14:47:22      NA         NA
4   95.23810 1523026043 2018-04-06 14:47:23      NA         NA
5   90.90909 1523026043 2018-04-06 14:47:23      NA         NA
6   88.23529 1523026044 2018-04-06 14:47:24      NA         NA
7   84.50704 1523026045 2018-04-06 14:47:25      NA         NA
8   84.50704 1523026045 2018-04-06 14:47:25      NA         NA
9   82.19178 1523026046 2018-04-06 14:47:26      NA         NA
10  80.00000 1523026047 2018-04-06 14:47:27      NA         NA
11  80.00000 1523026047 2018-04-06 14:47:27      NA         NA
12  81.08108 1523026048 2018-04-06 14:47:28      NA         NA
13  80.00000 1523026049 2018-04-06 14:47:29      NA         NA
14  78.94737 1523026050 2018-04-06 14:47:30      NA         NA
15  68.18182 1523026050 2018-04-06 14:47:30      NA         NA
16  60.00000 1523026051 2018-04-06 14:47:31      NA         NA
17  40.26846 1523026052 2018-04-06 14:47:32      NA         NA
18  49.18033 1523026054 2018-04-06 14:47:34      NA         NA
19  48.00000 1523026055 2018-04-06 14:47:35      NA         NA
20  48.38710 1523026056 2018-04-06 14:47:36      NA         NA
21  48.00000 1523026058 2018-04-06 14:47:38      NA         NA
22  49.18033 1523026059 2018-04-06 14:47:39      NA         NA
23  50.84746 1523026060 2018-04-06 14:47:40      NA         NA
24  52.17391 1523026061 2018-04-06 14:47:41      NA         NA
25  44.44444 1523026062 2018-04-06 14:47:42      NA         NA
26  47.61905 1523026064 2018-04-06 14:47:44      NA         NA
27  44.77612 1523026065 2018-04-06 14:47:45      NA         NA
28  43.79562 1523026066 2018-04-06 14:47:46      NA         NA
29  34.88372 1523026068 2018-04-06 14:47:48      NA         NA
30  36.58537 1523026069 2018-04-06 14:47:49      NA         NA
31  39.73510 1523026071 2018-04-06 14:47:51       1 1523026071

所以我希望 R 在遇到潜水开始时间时对这些前 30 秒的心率数据 (HR) 进行平均。理想情况下,我会在潜水开始时间的行中创建一个新列,即潜水前心率。

我试过 运行 如下所示的循环,但我只得到 NaN 值。我实际上是从 another post 得到这个循环的,但在我的情况下它似乎不起作用。我试着告诉 R,当纪元时间等于或大于潜水开始前 30 秒的时间,或者小于或等于潜水开始时间时,计算这段时间的 HR 平均值。但是我的代码没有让 R 知道它需要及时返回来计算平均值。

#setting up the column
df$prediveHR<-NA

# for each row
for (r in 1:nrow(df)) {
  # find all the rows within the acceptable timespan
  # note: figure out if you want < vs <=
  thisSubset = df[
    df$epoch[r] >= df$predivetime[r] &  
    df$epoch[r] <= df$dive_start[r]
  ,]
  # get the mean of the subset
  df$prediveHR[r] = mean(thisSubset$HR)
}

我假设每一行是一秒钟。从你提供的数据看来是这样。

results <- c()
for (i in 1:nrow(df){
  if (df$dive_start[i] != is.na(T){
    results[i] <- mean(df$HR[(i-29):i]
  }
}

如果第 dive_start 列不是 NA,我会询问每一行。如果它不是 NA,那么我们继续将 df$HR 的平均值写入结果向量。

我利用了这样一个事实,即在每次迭代中 i 等于当前行的数量。由于我们知道我们所在的行数,我们可以简单地减去 29 行作为我们的起始数字(在您的示例中 table 它将是 2),然后使用 i 作为 mean() 函数的结束行。

您可以通过这种方式轻松调整经期的长度。

这是一个基于{tidyverse}的解决方案。简而言之:

  1. 使用 tidyr::fill() 将潜水编号和开始时间传播回 pre-dive 周期,并使用它来计算潜水开始的秒数
  2. 在潜水开始后 30 秒内过滤到 pre-dive 行
  3. 计算每个 diveNum
  4. 内的平均 pre-dive HR
  5. 将计算的 pre-dive HR 合并回主数据帧
library(tidyverse)

pre_dive_data <- dive_data %>% 
  mutate(preDive = is.na(diveNum)) %>%
  fill(diveNum, dive_start, .direction = "up") %>%
  filter(preDive, dive_start - epoch <= 30) %>% 
  group_by(diveNum) %>%
  summarize(preDiveHR = mean(HR))

dive_data <- dive_data %>%
  left_join(pre_dive_data)

tail(dive_data)

输出:

# A tibble: 6 x 6
     HR      epoch datetime            diveNum dive_start preDiveHR
  <dbl>      <dbl> <dttm>                <dbl>      <dbl>     <dbl>
1  47.6 1523026064 2018-04-06 14:47:44      NA         NA      NA  
2  44.8 1523026065 2018-04-06 14:47:45      NA         NA      NA  
3  43.8 1523026066 2018-04-06 14:47:46      NA         NA      NA  
4  34.9 1523026068 2018-04-06 14:47:48      NA         NA      NA  
5  36.6 1523026069 2018-04-06 14:47:49      NA         NA      NA  
6  39.7 1523026071 2018-04-06 14:47:51       1 1523026071      65.5