Удаление переменных на основе среднего значения временного ряда в R

#r #time-series #subset #average

#r #временные ряды #подмножество #среднее

Вопрос:

У меня есть временной ряд в R (в примере dataframe я создал от 1 до 5 секунд; на самом деле он составляет от -2 до 20 секунд). Для каждого из этих случаев у меня есть значение переменной (в примере SD1 и SD2; на самом деле у меня есть серия из 49 значений). Я хочу определить все переменные, которые имеют среднее значение < 5 и > — 5 с интервалом от 2 секунд до 4 секунд. Как только они будут идентифицированы, я хочу удалить эти значения из набора данных, но сохранить остальные временные ряды в такте.

Пример фрейма данных

 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))

  

Я ценю любые отзывы по этому вопросу!

Комментарии:

1. Привет, непонятно следующее: «и > — 5 с интервалом от 2 секунд до 4 секунд».

2. Вы хотите удалить их или установить на NA ?

Ответ №1:

Мы можем извлечь значение between Time 2 и 4 секунды для каждого Participant и вычислить их mean . Замените значения на NA , если среднее значение больше 5. Мы можем использовать 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
  

Комментарии:

1. Спасибо вам за ответ! Это сработало отлично! Будьте осторожны!

Ответ №2:

Я не уверен, работает ли следующий код для вас

 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 amp; Time <= 4])) <= 5),1,NA)*SD1,
        SD2 = ifelse(all(abs(mean(SD2[Time >= 2 amp; Time <= 4])) <= 5),1,NA)*SD2
      )
    })
  )
)
  

или

 df %>%
  group_by(Participant) %>%
  mutate(SD1 = ifelse(all(abs(mean(SD1[Time >= 2 amp; Time <= 4])) <= 5), 1, NA) * SD1) %>%
  mutate(SD2 = ifelse(all(abs(mean(SD2[Time >= 2 amp; 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
  

Комментарии:

1. Спасибо за ответ! Я использовал приведенный выше код, поэтому мне не пришлось выписывать каждую пару SD, но я очень ценю вашу помощь!