Выявление выбросов в разных группах - PullRequest
2 голосов
/ 06 июня 2019

У меня есть набор данных, в котором участники были распределены по разным группам и прошли одинаковые тесты. Я знаю, что могу использовать агрегатную функцию для определения среднего значения и sd, но не могу понять, как найти выбросы в этих группах.

df<-read.table(header=T, text="id, group, test1, test2
1, 0, 57, 82
2, 0, 77, 80
3, 0, 67, 90
4, 0, 15, 70
5, 0, 58, 72
6, 1, 18, 44
7, 1, 44, 44
8, 1, 18, 46
9, 1, 20, 44
10, 1, 14, 38")

Мне нравится формат этого кода, но я не знаю, как его изменить, чтобы определить выбросы для каждой группы для каждого теста.

ТАКЖЕ, я хочу, чтобы выбросы считались чем-то большим, чем 2 стандартных отклонения, а не 3. Могу ли я отформатировать это тоже в этом коде?

##to get outliers on test1 if groups were combined
badexample <- boxplot(df$test1, plot=F)$out
which(df$test1 %in% badexample)

Это сработало бы, если бы я хотел, чтобы выбросы обеих групп были вместе на test1, но я хочу разделить по группам.

Вывод должен содержать: Выбросы для группы 0 на test1 выбросы для группы 0 на test2 выбросы для группы 1 на test1 выбросы для группы 1 на тесте 2

Ответы [ 3 ]

1 голос
/ 06 июня 2019

Вы можете написать функцию для вычисления выбросов и затем вызвать ее с помощью ave.

outlier <- function(x, SD = 2){
  mu <- mean(x)
  sigma <- sd(x)
  out <- x < mu - SD*sigma | x > mu + SD*sigma
  out
}

with(df, ave(test1, group, FUN = outlier))
# [1] 0 0 0 0 0 0 0 0 0 0

with(df, ave(test2, group, FUN = outlier))
# [1] 0 0 0 0 0 0 0 0 0 0

Чтобы иметь новые столбцы в df с этими результатами, присвойте их обычным способом.

df$out1 <- with(df, ave(test1, group, FUN = outlier))
df$out2 <- with(df, ave(test2, group, FUN = outlier))
0 голосов
/ 06 июня 2019

Вот способ с dplyr -

df %>% 
  mutate_at(
    vars(starts_with("test")),
    list(outlier = ~(abs(. - mean(.)) > 2*sd(.)))
  )

   id group test1 test2 test1_outlier test2_outlier
1   1     0    57    82         FALSE         FALSE
2   2     0    77    80         FALSE         FALSE
3   3     0    67    90         FALSE         FALSE
4   4     0    15    70         FALSE         FALSE
5   5     0    58    72         FALSE         FALSE
6   6     1    18    44         FALSE         FALSE
7   7     1    44    44         FALSE         FALSE
8   8     1    18    46         FALSE         FALSE
9   9     1    20    44         FALSE         FALSE
10 10     1    14    38         FALSE         FALSE
0 голосов
/ 06 июня 2019

Опция, используя data.table:

library(data.table)

df <- read.table(header=T, sep=",", text="id, group, test1, test2
1, 0, 57, 82
               2, 0, 77, 80
               3, 0, 67, 90
               4, 0, 15, 70
               5, 0, 58, 72
               6, 1, 18, 44
               7, 1, 44, 44
               8, 1, 18, 46
               9, 1, 20, 44
               10, 1, 14, 38")

DT <- as.data.table(df)
DT[, `:=`(mean1 = mean(test1), sd1 = sd(test1), mean2 = mean(test2), sd2 = sd(test2)), by = "group"]
DT[, `:=`(outlier1 = abs(test1-mean1)>2*sd1, outlier2 = abs(test2-mean2)>2*sd2)]
DT
#     id group test1 test2 mean1      sd1 mean2      sd2 outlier1 outlier2
#  1:  1     0    57    82  54.8 23.66854  78.8 8.074652    FALSE    FALSE
#  2:  2     0    77    80  54.8 23.66854  78.8 8.074652    FALSE    FALSE
#  3:  3     0    67    90  54.8 23.66854  78.8 8.074652    FALSE    FALSE
#  4:  4     0    15    70  54.8 23.66854  78.8 8.074652    FALSE    FALSE
#  5:  5     0    58    72  54.8 23.66854  78.8 8.074652    FALSE    FALSE
#  6:  6     1    18    44  22.8 12.04990  43.2 3.033150    FALSE    FALSE
#  7:  7     1    44    44  22.8 12.04990  43.2 3.033150    FALSE    FALSE
#  8:  8     1    18    46  22.8 12.04990  43.2 3.033150    FALSE    FALSE
#  9:  9     1    20    44  22.8 12.04990  43.2 3.033150    FALSE    FALSE
# 10: 10     1    14    38  22.8 12.04990  43.2 3.033150    FALSE    FALSE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...