Вычислите среднее значение для последовательности строк, удалите все, что составляет 1SD или больше, затем значение REPLACE, которое удаляется с помощью Mean - PullRequest
1 голос
/ 25 марта 2020

У меня большой набор данных из более чем 10000 строк: df:

  User              duration

  amy                582         
  amy                27
  amy                592
  amy                16
  amy                250
  tom                33
  tom                10
  tom                40
  tom                100

Желаемый результат:

User              duration

  amy                293.4         
  amy                27
  amy                293.4
  amy                16
  amy                250
  tom                33
  tom                10
  tom                40
  tom                45.75

Мы видим здесь все значения, превышающие 1SD от среднего значения для отдельной группы пользователей, были удалены, а затем заменены средним значением (уникального имени пользователя). Среднее значение для группы amy составляет 293,4. Среднее значение для группы составляет: 45,75

dput:

structure(list(User = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L), .Label = c("amy", "tom"), class = "factor"), duration = c(582L, 
27L, 592L, 16L, 250L, 33L, 10L, 40L, 100L)), class = "data.frame", row.names = c(NA, 
-9L))

Это то, что я пытался, как предложил один из члены здесь, и это работает fantasti c, я не уверен, как на самом деле сейчас ЗАМЕНИТЬ удаленные значения со средним для каждой группы:

 df %>% 
 group_by(User) %>%
 filter(between(duration, mean(duration) -  1 * sd(duration), 
 mean(duration) +  1 * sd(duration)))

Любое предложение приветствуется

1 Ответ

2 голосов
/ 25 марта 2020

Мы можем использовать replace

library(dplyr)
df %>% 
    group_by(User) %>%
    mutate(duration = replace(duration,
        !between(duration, mean(duration) -  1 * sd(duration), 
                 mean(duration) +  1 * sd(duration)), mean(duration)))

# A tibble: 9 x 2
# Groups:   User [2]
#  User  duration
#  <fct>    <dbl>
#1 amy      293. 
#2 amy       27  
#3 amy      293. 
#4 amy       16  
#5 amy      250  
#6 tom       33  
#7 tom       10  
#8 tom       40  
#9 tom       45.8

Или с base R

f1 <- function(x) as.numeric(abs(scale(x)) > 1)
with(df, ifelse(f1(duration), ave(duration, User), duration))
...