识别不同组中的离群值

时间:2019-06-06 20:08:01

标签: r

我有一个数据集,参与者被分配到不同的小组并完成了相同的测试。我知道我可以使用聚合函数来识别均值和标准差,但我无法弄清楚如何找到这些组中的离群值。

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上,但我想按组分开,则可以使用。

输出应包含: test1上第0组的离群值 test2上第0组的异常值 测试1上第1组的异常值 test2上第1组的异常值

3 个答案:

答案 0 :(得分:1)

您可以编写函数来计算离群值,然后使用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))

答案 1 :(得分:0)

使用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

答案 2 :(得分:0)

这里是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