2013-03-01 17 views
5

mam danych z dyskretnych wartości x, takie jakUsuwanie odstających łatwo w R

x = c(3,8,13,8,13,3,3,8,13,8,3,8,8,13,8,13,8,3,3,8,13,8,13,3,3) 
y = c(4,5,4,6,7,20,1,4,6,2,6,8,2,6,7,3,2,5,7,3,2,5,7,3,2); 

Jak można wygenerować nowy zestaw danych z wartościami x i y, gdzie wyeliminowania par wartości, w której wartość y jest 2 odchylenia standardowe powyżej średniej dla tego pojemnika. Na przykład, w pojemniku x = 3, 20 oznacza więcej niż 2 SD powyżej średniej, więc punkt danych powinien zostać usunięty.

Odpowiedz

6

dla mnie chcesz coś takiego:

by(dat,dat$x, function(z) z$y[z$y < 2*sd(z$y)]) 
dat$x: 3 
[1] 4 1 6 5 7 3 2 
--------------------------------------------------------------------------------------------------------------- 
dat$x: 8 
[1] 4 2 2 2 3 
--------------------------------------------------------------------------------------------------------------- 
dat$x: 13 
[1] 3 2 

EDIT po Komentarz:

by(dat,dat$x, 
      function(z) z$y[abs(z$y-mean(z$y))< 2*sd(z$y)]) 

EDIT

ja lekko zmienić by fu nction dostać X i Y, to zadzwonię rbind użyciu do.call

do.call(rbind,by(dat,dat$x,function(z) { 
           idx <- abs(z$y-mean(z$y))< 2*sd(z$y) 
           z[idx,] 
      })) 

lub używając plyr w jednej rozmowy

ddply(dat,.(x),function(z) { 
       idx <- abs(z$y-mean(z$y))< 2*sd(z$y) 
        z[idx,]}) 
+1

powinno to być 'z $ y <średnie (z $ y) + 2 * sd (z $ y)'? kiedy OP wspomniał "wartość y wynosi 2 odchylenia standardowe powyżej średniej dla tego bin" – liuminzhao

+0

@liuminzhao Myślę, że masz rację. – agstudy

+0

@liuminzhao Aktualizuję swoją odpowiedź. Myślę, że mój błąd wynika z formułowania pytań (muszę poprawić mój angielski :)) – agstudy

1

Coś takiego?

newdata <- cbind(x,y)[-which(y>2*sd(y)), ] 

A może masz na myśli coś takiego?

Data <- cbind(x,y) 
Data[-which(sd(y)>rowMeans(Data)), ] 
+0

To rozwiązanie nie usuwa odstających w 'y' przez bin (* to * oddzielnie dla każdej wartości' x'), ale w skali globalnej – QkuCeHBH

+0

prawo. Powinno to być zrobione przez bin .. – CodeGuy

2

Można użyć tapply za to, ale straci swoją pierwotną kolejność.

tapply(y,x,function(z) z[abs(z-mean(z))<2*sd(z)]) 
$`3` 
[1] 4 1 6 5 7 3 2 

$`8` 
[1] 5 6 4 2 8 2 7 2 3 5 

$`13` 
[1] 4 7 6 6 3 2 7 
+0

Jak mogę to zmienić w listę wartości x i y? – CodeGuy