2012-10-12 7 views
6

I ont une trame de données comme ceci:calculer les valeurs aberrantes dans 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 

I like pour effectuer le calcul de chaque cellule à la moyenne et écart-type pour calculer les valeurs aberrantes. Par exemple,

abs(x-Mean) > 3*SD 

x$count<-c(1) (incrémenter cette valeur si la condition ci-dessus est remplie). Je fais ceci pour vérifier l'anomalie dans mon ensemble de données. Si je connais les noms de colonnes, il serait plus facile de faire les calculs, mais le nombre de colonnes variera. Certaines cellules peuvent avoir NA dans les.

J'aime Subtrack dire de chaque cellule, et j'ai essayé ce

x$diff<-sweep(x, 1, x$Mean, FUN='-') 

ne semble pas fonctionner, des idées?

+1

Si vous nous fournissez un petit échantillon données avec 'dput (head (x))', alors nous pouvons simplement le couper et le coller dans nos navigateurs, et tester nos solutions. – nograpes

Répondre

30

Obtenez votre IQR (gamme interquartile) et inférieur/quartile supérieur en utilisant:

lowerq = quantile(data)[2] 
upperq = quantile(data)[4] 
iqr = upperq - lowerq #Or use IQR(data) 

Calculer les limites pour une valeur aberrante légère:

mild.threshold.upper = (iqr * 1.5) + upperq 
mild.threshold.lower = lowerq - (iqr * 1.5) 

Toutes les données pointent en dehors (> mild.threshold. supérieur ou < mild.threshold.lower) ces valeurs sont légèrement aberrantes

Pour détecter les extrêmes extrêmes, faites de même, mais multipliez par 3 à la place:

extreme.threshold.upper = (iqr * 3) + upperq 
extreme.threshold.lower = lowerq - (iqr * 3) 

Toutes les données point à l'extérieur (> extreme.threshold.upper ou < extreme.threshold.lower) ces valeurs est une valeur aberrante extrême

Hope this helps

modifier: accédait à 50%, pas 75%

+3

Devrait être 'upperq = quantile (données) [4]' – Ben

+0

Cela va être un très mauvais algorithme. Par exemple, prendre un vecteur assez grand où disons 80% des points de données sont dans une courte portée (par exemple 10-100) et reste 20% sont très clairsemés alors cet algorithme va identifier un grand nombre de valeurs aberrantes, ce qui peut ne pas donner une véritable idée des valeurs aberrantes dans la population – Bg1850

+2

La réponse donnée ici est une approche bien connue due à Tukey. Voir: https://en.wikipedia.org/wiki/Outlier#Tukey.27s_test – stackoverflowuser2010

3

J'ai vu que vous avez posé des questions sur les choses à faire par rangée. Vous devriez éviter cela. R suit le concept que les colonnes représentent les variables et les lignes représentent les observations. De nombreuses fonctions sont optimisées selon ce concept. Si vous avez besoin d'une sortie large ou transposée dans un fichier, vous pouvez réorganiser vos données juste avant d'écrire dans le fichier.

Je suppose que vos données ressemblent à la question, mais que vous avez plus d'une ligne.

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)) 

Résultat:

  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 
+0

Salut @Roland. Merci pour votre réponse. C'est un cas particulier où j'ai des milliers d'observations (lignes), que je voudrais découvrir les valeurs aberrantes et ensuite les représenter graphiquement seulement. Je transforme les dates en lignes et j'essaie de vérifier chaque cellule par rapport à la moyenne et compte le nombre de fois où elle a atteint ce point aberrant. Ensuite, je vais choisir 10 ou 20 des éléments et les représenter graphiquement. Fondamentalement, j'essaye d'attraper les anamolies dans mon ensemble de données. – user1471980

+0

@ user1471980, eh bien, ma réponse est un point de départ pour le faire. Ce n'est en fait pas difficile à faire en R (à condition que les données soient en format long et j'ai démontré comment y parvenir). Selon le nombre d'observations (vous écrivez des milliers mais cela pourrait aussi signifier des centaines de milliers) et des groupes de données, d'autres approches pourraient être préférables compte tenu du temps de calcul. Mais vous feriez mieux de poser une nouvelle question en donnant toutes les informations, y compris votre objectif final si ma réponse n'est pas suffisante. – Roland

+0

merci de votre contribution. Selon votre recommandation, j'ai créé une autre question, j'espère que j'ai fait un point - http://stackoverflow.com/questions/12888212/detecting-outliers-on-wide-data-frame – user1471980

4

Je l'ai utilisé @ réponse de BY0 ci-dessus pour créer une fonction qui supprime automatiquement les valeurs aberrantes.Voici la fonction et quelques exemples de code:

# 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 
0

Les formules suivantes peuvent être utilisées pour déterminer quelles valeurs sont les valeurs aberrantes:

upper.outlier.calc <- function(x.var, df){with(df, quantile(x.var, 0.75) + (1.5 * (quantile(x.var, 0.75) - quantile(x.var, 0.25))))}

lower.outlier.calc <- function(x.var, df){with(df, quantile(x.var, 0.25) - (1.5 * (quantile(x.var, 0.75) - quantile(x.var, 0.25))))}

Questions connexes