计算R中的异常值

use*_*980 9 r

我有一个这样的数据框:

X

Team 01/01/2012  01/02/2012  01/03/2012  01/01/2012 01/04/2012 SD Mean
A     100         50           40        NA         30       60  80
Run Code Online (Sandbox Code Playgroud)

我喜欢对每个单元格进行平均值和sd计算以计算异常值.例如,

abs(x-Mean) > 3*SD
Run Code Online (Sandbox Code Playgroud)

x$count<-c(1) (如果满足上述条件,则增加该值).

我这样做是为了检查我的数据集中的异常.如果我知道列名称,那么计算会更容易,但列数会有所不同.一些细胞可能含有NA.

我喜欢从每个单元格中减去平均值,我尝试了这个

x$diff<-sweep(x, 1, x$Mean, FUN='-')
Run Code Online (Sandbox Code Playgroud)

似乎没有工作,任何想法?

by0*_*by0 39

使用以下方法获取您的IQR(四分位数间距)和下/上四分位数:

lowerq = quantile(data)[2]
upperq = quantile(data)[4]
iqr = upperq - lowerq #Or use IQR(data)
Run Code Online (Sandbox Code Playgroud)

计算温和异常值的界限:

mild.threshold.upper = (iqr * 1.5) + upperq
mild.threshold.lower = lowerq - (iqr * 1.5)
Run Code Online (Sandbox Code Playgroud)

外部的任何数据点(> mild.threshold.upper或<mild.threshold.lower)这些值都是温和的异常值

要检测极端异常值,请执行相同的操作,而是乘以3:

extreme.threshold.upper = (iqr * 3) + upperq
extreme.threshold.lower = lowerq - (iqr * 3)
Run Code Online (Sandbox Code Playgroud)

外部的任何数据点(> extreme.threshold.upper或<extreme.threshold.lower)这些值都是极端异常值

希望这可以帮助

编辑:访问50%,而不是75%

  • 应该是`upperq = quantile(data)[4]` (3认同)
  • 由于Tukey,这里给出的答案是众所周知的方法.请参阅:https://en.wikipedia.org/wiki/Outlier#Tukey.27s_test (3认同)

tim*_*ham 8

我使用上面的@ by0的答案来创建一个自动删除异常值的函数.这是函数和一些示例代码:

# generate 10 random numbers and 2 'outlier' numbers
testData <- c(-42,rnorm(10),42)

# show the numbers
testData

# define a function to remove outliers
FindOutliers <- function(data) {
  lowerq = quantile(data)[2]
  upperq = quantile(data)[4]
  iqr = upperq - lowerq #Or use IQR(data)
  # we identify extreme outliers
  extreme.threshold.upper = (iqr * 3) + upperq
  extreme.threshold.lower = lowerq - (iqr * 3)
  result <- which(data > extreme.threshold.upper | data < extreme.threshold.lower)
}

# use the function to identify outliers
temp <- FindOutliers(testData)

# remove the outliers
testData <- testData[-temp]

# show the data with the outliers removed
testData
Run Code Online (Sandbox Code Playgroud)


Rol*_*and 5

我看到你问了一些关于按行做事的问题。你应该避免这种情况。R 遵循这样的概念:列代表变量,行代表观察值。很多功能都是根据这个理念进行优化的。如果您需要将宽输出或转置输出到文件,您可以在写入文件之前重新排列数据。

我假设您的数据实际上看起来如问题所示,但您有不止一行。

df <- read.table(text="Team 01/01/2012  01/02/2012  01/03/2012  01/01/2012 01/04/2012 SD 

Mean
A     100         50           40        NA         30       60  80
B     200         40           5         8          NA       NA  NA",check.names = FALSE,header=TRUE)

#needed because one date appears twice
df <- df[,]

#reshape the data
library(reshape2)
df <- melt(df,id="Team")
names(df)[2] <- "Date"

#remove the SD and Mean
df <- df[!df$Date %in% c("SD","Mean"),]

#function to detect outliers
outfun <- function(x) {
  abs(x-mean(x,na.rm=TRUE)) > 3*sd(x,na.rm=TRUE)
}

#test if function works
outfun(c(200,rnorm(10)))

#use function over all data
df3$outlier.all <- outfun(df3$value)

#apply function for each team 
library(plyr)
df3 <- ddply(df3,.(Team),transform,outlier.team=outfun(value))
Run Code Online (Sandbox Code Playgroud)

结果:

           Date Team value outlier.all outlier.team
1    01/01/2012    A   100       FALSE        FALSE
2    01/02/2012    A    50       FALSE        FALSE
3    01/03/2012    A    40       FALSE        FALSE
4  01/01/2012.1    A    NA          NA           NA
5    01/04/2012    A    30       FALSE        FALSE
6    01/01/2012    B   200       FALSE        FALSE
7    01/02/2012    B    40       FALSE        FALSE
8    01/03/2012    B     5       FALSE        FALSE
9  01/01/2012.1    B     8       FALSE        FALSE
10   01/04/2012    B    NA          NA           NA
Run Code Online (Sandbox Code Playgroud)