根据 R 中时间序列的平均值删除变量

Removing variables based on average of a time series in R

我在 R 中有一个时间序列(在示例数据框中我创建了 1 到 5 秒;实际上它从 -2 到 20 秒)。对于这些时间中的每一次,我都有一个变量值(在示例 SD1 和 SD2 中;实际上我有 49 个值系列)。我想确定从 2 秒到 4 秒的平均值为 < +5 和 > - 5 的所有变量。一旦它们被识别出来,我想从数据集中删除这些值,但保持时间序列的其余部分不变。

示例数据框

df1 <- data.frame(Participant = c('A', 'A', 'A', 'A', 'A', 'B', 'B','B','B','B','C', 'C', 'C', 'C', 'C' ), 
                  Time = c(1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5), 
                  SD1 = c(-10,-10,-10,-10,-10,50, 50, 50,50,50,1,1, 1,1,1), 
                  SD2 = c(0, 50, 50, 50,0, 0,0,0,1,50, 0,0,0,1,50))

所以我最终会得到这样的结果:

df2 <- data.frame(Participant = c('A', 'A', 'A', 'A', 'A', 'B', 'B','B','B','B','C', 'C', 'C', 'C', 'C' ), 
                  Time = c(1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5), 
                  SD1 = c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,1,1, 1,1,1), 
                  SD2 = c(NA,NA,NA,NA,NA, 0,0,0,1,50, 0,0,0,1,50))

我感谢关于此问题的所有反馈!

我不确定下面的代码是否适合你

do.call(
  rbind,
  c(
    make.row.names = FALSE,
    lapply(split(df, df$Participant), function(v) {
      transform(v,
        SD1 = ifelse(all(abs(mean(SD1[Time >= 2 & Time <= 4])) <= 5),1,NA)*SD1,
        SD2 = ifelse(all(abs(mean(SD2[Time >= 2 & Time <= 4])) <= 5),1,NA)*SD2
      )
    })
  )
)

df %>%
  group_by(Participant) %>%
  mutate(SD1 = ifelse(all(abs(mean(SD1[Time >= 2 & Time <= 4])) <= 5), 1, NA) * SD1) %>%
  mutate(SD2 = ifelse(all(abs(mean(SD2[Time >= 2 & Time <= 4])) <= 5), 1, NA) * SD2)

双方都在给予

   Participant Time SD1 SD2
1            A    1  NA  NA
2            A    2  NA  NA
3            A    3  NA  NA
4            A    4  NA  NA
5            A    5  NA  NA
6            B    1  NA   0
7            B    2  NA   0
8            B    3  NA   0
9            B    4  NA   1
10           B    5  NA  50
11           C    1   1   0
12           C    2   1   0
13           C    3   1   0
14           C    4   1   1
15           C    5   1  50

我们可以为每个Participant提取值between Time 2秒和4秒并计算它们的mean。如果平均值大于 5,则将值替换为 NA。我们可以使用 across 将函数应用于多个列。

library(dplyr)

df %>%
  group_by(Participant) %>%
  mutate(across(SD1:SD2, ~if(abs(mean(.[between(Time, 2, 4)])) > 5) NA else .))

#   Participant  Time   SD1   SD2
#   <chr>       <dbl> <dbl> <dbl>
# 1 A               1    NA    NA
# 2 A               2    NA    NA
# 3 A               3    NA    NA
# 4 A               4    NA    NA
# 5 A               5    NA    NA
# 6 B               1    NA     0
# 7 B               2    NA     0
# 8 B               3    NA     0
# 9 B               4    NA     1
#10 B               5    NA    50
#11 C               1     1     0
#12 C               2     1     0
#13 C               3     1     0
#14 C               4     1     1
#15 C               5     1    50