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