如何使用 tidyverse 去除基于标准开发的异常值?

Posted

技术标签:

【中文标题】如何使用 tidyverse 去除基于标准开发的异常值?【英文标题】:how to remove outliers based on standard dev, using tidyverse? 【发布时间】:2020-04-09 16:35:07 【问题描述】:

我使用 tidyverse 包尝试了这段代码来过滤基于 sd 的异常值。

rt_trimmed_data_Dec = data_Dec %>%
 group_by(Time_of_Testing, Item_Type, Group) %>%
 summarise(RT_mean = mean(RT, na.rm=TRUE), RT_sd = sd(RT, na.rm=TRUE))%>%
 ungroup()  %>%
 mutate(rt_high = RT_mean + (2.5 * RT_sd)) %>%
  mutate(rt_low = RT_mean - (2.5 * RT_sd))

然后,我尝试加入两个数据框,以应用过滤掉。

data_Dec_RT = data_Dec %>%
   inner_join(rt_trimmed_data_Dec) %>%
   filter(RT < rt_high) %>%
    filter(RT > rt_low)

然后我得到了这个错误

Error: `by` required, because the data sources have no common variables

致电rlang::last_error() 以查看回溯。 > rlang::last_error() 消息:by 必填,因为数据源没有公共变量 班级:rlang_error 回溯: 1. dplyr::inner_join(., rt_trimmed_data_Dec) 9. dplyr:::common_by.NULL(by, x, y) 11. dplyr:::bad_args("by", "必填,因为数据源没有公共变量") 12. dplyr:::glubort(fmt_args(args), ..., .envir = .envir) 13. dplyr::inner_join(., rt_trimmed_data_Dec)。

您能否就如何解决此问题提出建议,非常感谢您的帮助。

【问题讨论】:

你在哪里合并??没有公共列(同名),您也没有定义它们。 R 应该如何知道在哪里合并? 确保rt_trimmed_data_Dec 具有与data_Dec 相同的列,否则,在inner_join 中定义by 并使用您要在两个数据帧中使用的列。有关详细信息,请参阅?inner_join 【参考方案1】:

这很容易做到,只需使用 scale 对 RT 列进行 z 评分。

    library(tidyverse)

    samples = 50
    Ps = 10

    # data frame that contains participant numbers, and RT scores
    data <- data.frame(participant = as.factor(rep(1:Ps, each = samples)),
                       RT = rnorm(n = samples*Ps, mean = 600, sd = 50))

    data_noOutliers <- data %>% 
      group_by(participant) %>% 
      mutate(zRT = scale(RT)) %>% 
      filter(between(zRT,-2.5,+2.5))

【讨论】:

非常感谢您的大都市汤姆。我不知道 scale() 可以做到这一点。它比我拥有的代码要快得多,也更有意义。那么,在我的报告中,我可以说异常值是基于 SD 值还是基于 Z 分数被删除的? z 分数是 RT 的标准化版本,其中 +1 是高于平均值 1SD 的值。因此你可以在zRT的基础上去掉2.5以上和以下。 en.wikipedia.org/wiki/Standard_score 非常感谢汤姆的澄清,非常感谢。【参考方案2】:

我猜你可以这样做

library(dplyr)
data_Dec %>%
  group_by(Time_of_Testing, Item_Type, Group) %>%
  filter(between(RT, mean(RT, na.rm=TRUE) - (2.5 * sd(RT, na.rm=TRUE)), 
                     mean(RT, na.rm=TRUE) + (2.5 * sd(RT, na.rm=TRUE))))

【讨论】:

非常感谢您的帮助 Ronak,代码运行良好。那么,代码是否以与我所拥有的类似但更快的方式工作: filter(RT % filter(RT > rt_low) ?再次感谢您的贡献。 @azizitamimi 你不需要使用filter 两次。您可以将两个filter 条件组合在一起。此外,我避免使用 summarise 创建新列,然后加入,这样会更快。

以上是关于如何使用 tidyverse 去除基于标准开发的异常值?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用基于字段值选择的异构委托制作 QtQuick TableView / TreeView

tidyverse 是不是提供基于 xts 范围的查询?

如何使用 R 处理 OLS 中的异方差性

使用过滤器/变异和 dplyr/tidyverse 逻辑对数据库进行分类[重复]

基于Spark的异构分布式深度学习平台

一种基于结构信息检索文档的思路(html,pdf,html,xml,doc,ppt,这样的异构文档应该如何检索呢?)