R - 如何通过两个不同的组从数据集中删除异常值

R - how to remove outliers from dataset by two different groups

我想制作一个函数,从我的数据集中删除所有离群值。我已经阅读了很多关于此的 Stack Overflow 文章,所以我知道删除异常值的危险,但到目前为止我看到的所有函数都不适合我的数据类型。这是我目前所拥有的:

我的最小数据集示例:

ID, Treatment, conc, relabs
1, A, 40.00, 1.0793923
2, A, 40.00, 0.6436631
3, A, 40.00, 0.5556844
4, A, 40.00, 0.4834845
5, A, 40.00, 0.7224756
6, A, 40.00, 0.6804259
7, A, 20.00, 0.9958288
8, A, 20.00, 0.7099360
9, A, 20.00, 0.7028124
10, A, 20.00, 0.5016352
11, A, 20.00, 0.6860346
12, A, 20.00, 0.7341970
13, A, 10.00, 0.8175491
14, A, 10.00, 0.6900910
15, A, 10.00, 0.5278228
16, A, 10.00, 0.7560026
17, A, 10.00, 0.8841343
18, A, 10.00, 0.6687616
19, A, 5.00, 0.8563232
20, A,  5.00, 0.7419997
21, B, 0.80, 1.2049695
22, B, 0.80, 0.4969811
23, B, 0.80, 0.2835814
24, B, 0.80, 0.6700250
25, B, 0.80, 1.3126651
26, B, 0.80, 0.4510617
27, B, 0.60, 0.7629639
28, B, 0.60, 0.7513716
19, B, 0.60, 0.7956074

我使用 rstatix 包中的 identify_outliers 函数通过不同的处理和浓度来识别异常值,它为我提供了包含两个新列 is.outlieris.extreme 的数据框。

df_outliers <-
df %>% 
  group_by(Treatment, conc) %>% 
  identify_outliers("relabs") 

df_outliers

然后我通过从 df_outliers 数据框的 dplyr 包中粘贴 slice 函数中的 ID 来手动删除异常值,如果我有更大的数据集,这会很麻烦:

df_wo_outliers <- 
  df %>% 
  slice(-c(1, 7, 10, 19 )) %>% 
  select(-ID)

df_wo_outliers

我不知何故需要从我的原始数据集 relabs 列中自动删除 is.outlier = TRUE 的行。

这意味着在该浓度(可变浓度)和处理(可变处理)内,相对吸收(可变 relabs)太高或太低(Q3 + 1.5xIQR/Q1 - 1.5xIQR)。

我愿意听取有关该功能的任何建议或编写我自己的建议,但是我不确定如何过滤数据以便它会删除数据集中不同组中的异常值,我的意思是处理和浓缩和并不是我所看到的整个数据集都被谈论了很多。

还有,有没有办法以类似的方式计算置信区间?由于我还没有以正确的方式过滤我的数据集,我相信我会遇到类似的问题

如果需要,我还会附上我的部分数据的图片: section of my data set

我正在研究 Windows 10,R 版本 1.3.1073

您可以为此使用 dplyr::filter()。既然要保留is.outlier == FALSE,就需要用感叹号作为取反运算

library(dplyr)
df_no_outliers <- df %>%
  group_by(Treatment, conc) %>%
  identify_outliers("relabs") %>%
  filter(!is.outlier)

您可以在获取异常值后在 dplyr 中使用 anti_join()。请注意,在我的 df_outliers 中,我只有 IDs 1、7 和 10。

library(tidyverse)
library(rstatix)

df <- tibble(
                ID = c(1L,2L,3L,4L,5L,6L,7L,8L,
                       9L,10L,11L,12L,13L,14L,15L,16L,17L,18L,19L,
                       20L,21L,22L,23L,24L,25L,26L,27L,28L,19L),
         Treatment = c("A","A","A","A","A","A",
                       "A","A","A","A","A","A","A","A","A","A","A","A",
                       "A","A","B","B","B","B","B","B","B","B","B"),
              conc = c(40,40,40,40,40,40,20,20,
                       20,20,20,20,10,10,10,10,10,10,5,5,0.8,0.8,
                       0.8,0.8,0.8,0.8,0.6,0.6,0.6),
            relabs = c(1.0793923,0.6436631,0.5556844,
                       0.4834845,0.7224756,0.6804259,0.9958288,0.709936,
                       0.7028124,0.5016352,0.6860346,0.734197,0.8175491,
                       0.690091,0.5278228,0.7560026,0.8841343,0.6687616,
                       0.8563232,0.7419997,1.2049695,0.4969811,0.2835814,0.670025,
                       1.3126651,0.4510617,0.7629639,0.7513716,0.7956074)
)

df_outliers <- df %>% 
  group_by(Treatment, conc) %>% 
  identify_outliers("relabs") 

# A tibble: 3 x 6
  Treatment  conc    ID relabs is.outlier is.extreme
  <chr>     <dbl> <int>  <dbl> <lgl>      <lgl>     
1 A            20     7  0.996 TRUE       TRUE      
2 A            20    10  0.502 TRUE       TRUE      
3 A            40     1  1.08  TRUE       FALSE  

# without outliers
df %>% 
  anti_join(df_outliers, by = "ID") %>% 
  view()

# A tibble: 26 x 4
      ID Treatment  conc relabs
   <int> <chr>     <dbl>  <dbl>
 1     2 A            40  0.644
 2     3 A            40  0.556
 3     4 A            40  0.483
 4     5 A            40  0.722
 5     6 A            40  0.680
 6     8 A            20  0.710
 7     9 A            20  0.703
 8    11 A            20  0.686
 9    12 A            20  0.734
10    13 A            10  0.818
# … with 16 more rows