【问题标题】:How to exclude outliers individually for target & participant in R如何为 R 中的目标和参与者单独排除异常值
【发布时间】:2020-03-05 20:46:34
【问题描述】:

我是(非常)R 新手,我想知道是否可以得到一些帮助。我想知道如何排除每个参与者的平均反应时间和每个目标的平均反应时间的两个标准差的异常值并将其替换为 na。

我的数据如下所示:

ptp  rt    group   target
1    1094  E       dog
1    2100  E       hat
2    918   E       dog
2    1211  E       hat
3    1142  E       dog
3    1222  E       hat
1    10    W       dog
1    993   W       hat
2    897   W       dog
2    1078  W       hat
3    4002  W       dog
3    899   W       hat

我已经计算了每个参与者和项目的平均值和标准差

mean <- tapply(data$rt, data$target, mean)
sd <-  tapply(data$rt, data$target, sd)
mean <-  tapply(data$rt, data$ptp, mean)
sd <- tapply(data$rt, data$ptp, sd)

但是,我是 R 的超级新手,我编写代码来计算平均值的两个标准偏差(平均值+1.96*SD 和平均值-1.96*SD),并将所有超出范围的值转换为NA的参与者都超出了我的范围。一定有比手工更简单的方法!任何帮助将不胜感激。

非常感谢, 仁

【问题讨论】:

  • 你会接受任何答案吗?

标签: r outliers standard-deviation


【解决方案1】:

要获得漂亮的汇总统计信息,您可以使用aggregate()

aggregate(rt ~ target + ptp, dat, function(x) c(mean=mean(x), sd=sd(x), sd196=sd(x)*1.96))
#   target ptp    rt.mean      rt.sd rt.sd196
# 1    dog   1  552.00000  766.50375 1502.34735
# 2    hat   1 1546.50000  782.76721 1534.22373
# 3    dog   2  907.50000   14.84924   29.10452
# 4    hat   2 1144.50000   94.04520  184.32860
# 5    dog   3 2572.00000 2022.32539 3963.75777
# 6    hat   3 1060.50000  228.39549  447.65516

对于排除(假设您想排除每个 "target" 的全部观察值),您可以使用 ave() 将数据子集设置为 NA

dat$rt[with(dat, ave(rt, target, ptp, FUN=function(x) mean(x)/sd(x))) > 1.96] <- NA
#    ptp   rt group target
# 1    1 1094     E    dog
# 2    1   NA     E    hat
# 3    2   NA     E    dog
# 4    2   NA     E    hat
# 5    3 1142     E    dog
# 6    3   NA     E    hat
# 7    1   10     W    dog
# 8    1   NA     W    hat
# 9    2   NA     W    dog
# 10   2   NA     W    hat
# 11   3 4002     W    dog
# 12   3   NA     W    hat

为了不排除整个参与者,请不要将ptp 包含到ave() 中并执行以下操作:

dat$rt[with(dat, ave(rt, target, FUN=function(x) mean(x)/sd(x))) > 1.96] <- NA

注意:如果名称尚未分配给函数,请事先检查。在您的示例中,您创建了与 mean()sd() 函数的冲突。

数据

dat <- structure(list(ptp = c(1L, 1L, 2L, 2L, 3L, 3L, 1L, 1L, 2L, 2L, 
3L, 3L), rt = c(1094L, 2100L, 918L, 1211L, 1142L, 1222L, 10L, 
993L, 897L, 1078L, 4002L, 899L), group = c("E", "E", "E", "E", 
"E", "E", "W", "W", "W", "W", "W", "W"), target = c("dog", "hat", 
"dog", "hat", "dog", "hat", "dog", "hat", "dog", "hat", "dog", 
"hat")), row.names = c(NA, -12L), class = "data.frame")

【讨论】:

    【解决方案2】:

    根据我的经验,最好的方法是:

    library(dplyr)
    
    data_2SD <- data %>% 
      group_by(ptp,target) %>% 
      mutate_at(vars(rt), ~replace(.x, abs(scale(.x)) >= 2, NA))
    

    在您的情况下,没有这样的观察结果,按每个ptptarget 分组,它们大于或小于其平均反应时间的两个标准差:

    输出:

    > data_2SD
    # A tibble: 12 x 4
    # Groups:   ptp, target [6]
         ptp    rt group target
       <dbl> <dbl> <chr> <chr> 
     1     1  1094 E     dog   
     2     1  2100 E     hat   
     3     2   918 E     dog   
     4     2  1211 E     hat   
     5     3  1142 E     dog   
     6     3  1222 E     hat   
     7     1    10 W     dog   
     8     1   993 W     hat   
     9     2   897 W     dog   
    10     2  1078 W     hat   
    11     3  4002 W     dog   
    12     3   899 W     hat
    

    【讨论】:

      猜你喜欢
      • 2020-08-15
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 1970-01-01
      • 2015-03-11
      • 2012-08-11
      • 2012-05-21
      • 1970-01-01
      相关资源
      最近更新 更多