如何检测单变量异常值并在新列中标记为TRUE或FALSE

5

我有一个包含30列和超过10,000行的数据框。

如何运行离群值分析,针对一组变量返回一个TRUE(如果任何变量超过特定阈值),或者如果所有变量的异常值阈值(3SDs)未达到,则返回FALSE,并在一个新列中显示TRUE/FALSE值?

我已使用quantile找到每个变量的3个标准差截止值:

例如:

quantile(df$a, 0.003, na.rm = T) #and 

quantile(df$a, 0.997, na.rm = T)

假设该变量的第一个值为2.5,上限值为10.5,我随后创建了一个新变量:

df$outliers <- (df$a <- df$a <2.5 | df$a > 10.5)

当列a中的值小于2.5或大于10.5时,该函数会返回TRUE值。

我想做的是,让df$outliers代表一组列(不仅仅是一个列)的离群值状态,例如d、e、f、g、l、m等列,它们都有自己的阈值需要满足。

最好的方法是什么?

2个回答

3
假设您的数据框名为df,您感兴趣检查异常值的列为abc(存储在cols中)。我们可以在这些列上使用sapply来找出哪些值位于异常值范围内。这将返回一个由TRUE/FALSE值组成的矩阵,指示该特定值是否为异常值。我们对其进行rowSums并在该行中任何一列具有TRUE值时分配值TRUE,否则分配值FALSE。"最初的回答"
cols <- c("a", "b", "c")

df$outliers <- rowSums(sapply(df[cols], function(x) 
                       x < quantile(x, 0.003) | x > quantile(x, 0.997))) > 0

df
#             a          b          c random outliers
#1  -0.56047565  1.2240818 -1.0678237      1    FALSE
#2  -0.23017749  0.3598138 -0.2179749      2    FALSE
#3   1.55870831  0.4007715 -1.0260044      3    FALSE
#4   0.07050839  0.1106827 -0.7288912      4    FALSE
#5   0.12928774 -0.5558411 -0.6250393      5    FALSE
#6   1.71506499  1.7869131 -1.6866933      6     TRUE
#7   0.46091621  0.4978505  0.8377870      7    FALSE
#8  -1.26506123 -1.9666172  0.1533731      8     TRUE
#9  -0.68685285  0.7013559 -1.1381369      9    FALSE
#10 -0.44566197 -0.4727914  1.2538149     10     TRUE

data

set.seed(123)
df <- data.frame(a = rnorm(10), b = rnorm(10), c = rnorm(10), random = 1:10)

嗨Ronak,感谢你的回应-这正是我希望实现的。不幸的是,我遇到了以下错误:“Error in'[.data.table'(df,cols):当i是data.table(或字符向量)时,必须使用'on ='参数指定要加入的列(请参见?data.table),或者通过将x键入(即已排序并标记为排序,请参见?setkey)。由于x在RAM中排序,因此键掉加入可能具有进一步的速度优势。”你知道问题可能是什么吗?干杯! - stat.chat
@stat.chat,你有data.table,能否将其转换为data.frame,然后尝试上述操作? - Ronak Shah
嗨Ronak,谢谢你。不过我还有另一个错误。很抱歉我还是R的新手!错误信息是:“如果na.rm为FALSE,则不允许缺失值和NaN。” 我已经尝试在代码中添加na.rm = TRUE,无论是在[cols]之后还是在最后一个括号之前,但它都不起作用,并弹出“意外符号错误”。我应该把na.rm = T放在哪里? - stat.chat
我在sappy之后添加了na.rm,即:sapplyna.rm = T(df [cols],function ... 但是现在我遇到了这个错误:Error: attempt to apply non-function。 - stat.chat
@stat.chat 你需要在quantile函数中添加该参数。尝试使用以下代码:df$outliers <- rowSums(sapply(df[cols], function(x) x < quantile(x, 0.003, na.rm = TRUE) | x > quantile(x, 0.997, na.rm = TRUE))) > 0 - Ronak Shah

0
通常情况下,如果一个观测值在一个或多个特征中被认为是异常值,那么它就是一个异常值。但我不知道你正在处理什么,所以可能会有所不同,你必须找出你所处理的问题如何定义异常值,然后选择重要的特征和阈值。
回到第一个定义,你可以将列创建为所有变量相同过程结果的交集。
然而,你应该避免手动操作,所以你需要创建一个包含所有变量阈值的表,然后创建一个函数,如果观测值对于至少一个变量是异常值,则返回true。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接