2012-10-12 10 views
6

mam ramki danych tak:obliczania wartości odchylenia w 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 jak przeprowadzić obliczenia każdej komórki na średnią i odchylenie standardowe obliczenia błędne. Na przykład:

abs(x-Mean) > 3*SD 

x$count<-c(1) (zwiększ tę wartość, jeśli powyższy warunek jest spełniony).

Robię to, aby sprawdzić anomalię w moim zbiorze danych. Jeśli znam nazwy kolumn, łatwiej byłoby wykonać obliczenia, ale liczba kolumn będzie się różnić. Niektóre komórki mogą zawierać NA.

Lubię podścieżka znaczy z każdej komórki, a ja próbowałem

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

nie wydaje się działać, jakieś pomysły?

+1

Jeśli podasz nam małą próbkę dane z 'dput (head (x))', możemy po prostu wyciąć i wkleić do naszych przeglądarek i przetestować nasze rozwiązania. – nograpes

Odpowiedz

30

Pobierz IQR (przedział międzykwartylowy) i dolna/górna kwartyl używając:

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

obliczyć granice dla łagodnego odstający:

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

Wszelkie danych Temperatura na zewnątrz (> mild.threshold. górny lub < mild.threshold.lower) te wartości są łagodnym odchyłką.

Aby wykryć ekstremalne wartości odstające, wykonaj to samo, ale pomnóż przez 3 zamiast:

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

Wszelkie dane wskazują na zewnątrz (> extreme.threshold.upper lub < extreme.threshold.lower) tych wartości jest skrajnym poboczna

Nadzieja to pomaga

edit: 50% było dostępu, nie 75%

+3

Powinien być 'upperq = quantile (data) [4]' – Ben

+0

To będzie bardzo zły algorytm. Przykładowo, weź dość duży wektor, gdzie powiedzmy, że 80% punktów danych jest w krótkim zakresie (np. 10-100) i reszta 20% jest bardzo rzadka, wtedy ten algorytm zidentyfikuje ogromną liczbę wartości odstających, co może nie dać prawdziwego poczucia wartości odstających w populacji – Bg1850

+2

Podana tutaj odpowiedź jest dobrze znanym podejściem wynikającym z Tukeya. Zobacz: https://en.wikipedia.org/wiki/Outlier#Tukey.27s_test – stackoverflowuser2010

3

Widziałem, że zadałeś kilka pytań na temat robienia rzeczy po kolei. Powinieneś tego unikać. R podąża za koncepcją, że kolumny reprezentują zmienne i wiersze reprezentują obserwacje. Wiele funkcji jest zoptymalizowanych zgodnie z tą koncepcją. Jeśli potrzebujesz szerokiego lub transponowanego wyjścia do pliku, możesz zmienić układ danych tuż przed zapisaniem do pliku.

Zakładam, że twoje dane rzeczywiście wyglądają tak, jak pokazano w pytaniu, ale masz więcej niż jeden wiersz.

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

Wynik:

  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

Witam @Roland. Dziękuję za odpowiedź. Jest to szczególny przypadek, w którym mam tysiące obserwacji (wierszy), że chciałbym znaleźć wartości odstające, a następnie je tylko wykreślić. Zmieniam daty na wiersze i próbuję sprawdzić każdą komórkę pod kątem średniej i liczby zliczeń, ile razy osiągnął ten punkt odstający. Następnie wybiorę 10 lub 20 elementów i wyrysuję je. Zasadniczo próbuję złapać anamolie w moim zbiorze danych. – user1471980

+0

@ user1471980, cóż, moja odpowiedź jest punktem wyjścia do zrobienia tego. W rzeczywistości R nie jest trudne (pod warunkiem, że dane są w długim formacie i pokazałem, jak to osiągnąć). W zależności od liczby obserwacji (ty piszesz tysiące, ale może to również oznaczać sto tysięcy) i grup danych, inne podejścia mogą być lepsze, biorąc pod uwagę czas obliczeń. Lepiej jednak zadać nowe pytanie, podając wszystkie informacje, w tym cel końcowy, jeśli moja odpowiedź nie jest wystarczająca. – Roland

+0

dziękuję za twój wkład. Zgodnie z twoją rekomendacją, stworzyłem kolejne pytanie, mam nadzieję, że zrobiłem punkt - http://stackoverflow.com/questions/12888212/detecting-outliers-on-wide-data-frame – user1471980

4

Użyłem @ odpowiedź by0 za wyżej utworzyć funkcję, która automatycznie usuwa błędne.Oto funkcja, a niektóre przykładowy kod:

# 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

następujące wzory mogą być wykorzystane do określenia, które wartości są odstających:

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

Powiązane problemy