R函数找到列中异常值的百分比?

时间:2015-09-05 14:11:32

标签: r function outliers

我需要创建一个函数来计算数据框列中异常值的百分比。对于异常值,我的意思是任何数据点与均值相差超过3个标准差。

我查看了包outlier,但这并没有让我感到厌烦,因为所有功能似乎都是针对寻找异常值而不是计算它们。

我可以使用它的功能吗?

3 个答案:

答案 0 :(得分:6)

我认为这个功能是你需要的:

outliersper <- function(x){
  length(which(x >  mean(x) + 3 * sd(x) | x < mean(x) - 3 * sd(x))  ) / length(x)
}

示例数据

#3 outliers here
df <- data.frame(col= c(1000,1000,1000,runif(100)))

#function
> outliersper(df$col)
[1] 0.02912621

验证

> length(which(df$col > (3 * sd(df$col))))
[1] 3
> 3/length(df$col)
[1] 0.02912621

答案 1 :(得分:5)

这样的话,假设x是数据框中的一列?

set.seed(321)
x <- rnorm(10000)
x[x > mean(x) + 3*sd(x) | x < mean(x) - 3*sd(x)]
 [1]  3.135843 -3.006514  3.227549 -3.255502  3.065514  3.159309 -3.171849
 [8]  3.215432  3.120442  3.352662  3.574360  3.424063  3.126673 -3.024961
[15] -3.153842 -3.263268 -3.032526  3.179344 -3.605372

获得异常值的百分比

outli <- x[x > mean(x) + 3*sd(x) | x < mean(x) - 3*sd(x)]
length(outli) / length(x)
[1] 0.0019

并使其成为一个功能

find_outlier <- function(x, num=3) {
  mean(x > mean(x) + num*sd(x) | x < mean(x) - num*sd(x))
}


find_outlier(x)
[1] 0.0019

答案 2 :(得分:2)

这是dplyr方法:

library(dplyr)

# Fake data
set.seed(54)
dat = as.data.frame(replicate(5, rnorm(10000)))

set.seed(321)
dat$ExtraCol <- rnorm(10000)

# Number of SDs to be considered an outlier
n=3

在下面的代码中,.是一个&#34;代词&#34;含义&#34;数据框的当前列dat&#34;。

# Percent outliers in every column
dat %>% 
  summarise_each(funs(sum(. > mean(.) + n*sd(.) | . < mean(.) - n*sd(.))/n()))

      V1     V2     V3     V4     V5 ExtraCol
1 0.0031 0.0039 0.0024 0.0028 0.0022   0.0019

还有多种方法可以选择特定的列。

# Columns 1, 3, and 6
dat %>% 
  summarise_each(funs(sum(. > mean(.) + n*sd(.) | . < mean(.) - n*sd(.))/n()), 
                 c(1,3,6))

      V1     V3 ExtraCol
1 0.0031 0.0024   0.0019

# Columns whose name includes "Extra"
dat %>% 
  summarise_each(funs(sum(. > mean(.) + n*sd(.) | . < mean(.) - n*sd(.))/n()), 
                 matches("Extra"))

  ExtraCol
1   0.0019

# Select only numeric columns
dat$Letters = sample(LETTERS, 10000, replace=TRUE)

dat %>% 
  summarise_each(funs(sum(. > mean(.) + n*sd(.) | . < mean(.) - n*sd(.))/n()),
                 which(sapply(., is.numeric)))

      V1     V2     V3     V4     V5 ExtraCol
1 0.0031 0.0039 0.0024 0.0028 0.0022   0.0019