2014-03-25 2 views
1

mad 함수를 사용하여 Rstats 패키지에서 outliers를 식별합니다. aggregate 사용, 정말 같은 요인 수준의 각각의 고유 한 조합에 대해 경계 값을 찾을 수 있습니다집계 결과를 부분 집합 데이터로 사용 R

require(stats) 
set.seed(492) 
y <- rnorm(2000) 
x1 <- sample(letters[1:2], 2000,T) 
x2 <- sample(letters[1:2], 2000,T) 
df <- data.frame(y,x1,x2) 

boundaries <- aggregate(df$y, list(df$x1, df$x2), function(x) cbind(median(x) 
+ (3*mad(x)), median(x) - (3*mad(x)))) 

주는 :

+---------------------------------------+ 
| Group.1 Group.2  x.1  x.2 | 
+---------------------------------------+ 
| 1  a  a 2.875560 -2.809068 | 
| 2  b  a 2.867109 -2.843691 | 
| 3  a  b 3.137889 -2.960135 | 
| 4  b  b 3.091169 -3.134296 | 
+---------------------------------------+ 

x.1은 상한과 x.2은 하한이다. 하위 수준의 을 사용하여 요인 수준의 각 조합에 대해 이상 값이 제거되도록합니다. 예를 들어, 2.88 이상 또는 -2.80보다 큰 값은 원하지 않지만 ab의 경우에는 상한값을 3.14로 설정하고 낮은 컷 - 오프는 -2.96이다.

은 지금까지 내가 by를 사용하여 시도했지만, 그것은 길이가 0 행에있는 데이터 프레임 반환 : 모든 지침은 많이 감사합니다

by(df$y, list(df$x1, df$x2), function(x) df[which(df$y>(median(x) + (3*mad(x))) &  df$y<(median(x) - (3*mad(x)))),]) 

합니다.

+0

"x.2"도 하단 컷오프를 나타 냅니까? – A5C1D2H2I1M1N2O1R2T1

+0

예, 죄송합니다! 나는 그 질문에서 분명히 할 것이다. – luser

답변

1

다음은 plyr을 사용하는 해결책입니다. split-apply-combine 패러다임을 사용합니다. 먼저 x1x2 열을 사용하여 데이터 프레임을 분할합니다. 각 부분에 대해 d (데이터 프레임 임)에 대해 우리는 y을 외계인이라고 생각한 한계를 계산 한 다음 논리적 색인을 사용하여 이상치가 아닌 d의 행만 반환합니다. 마지막으로, ddply은 서브 세트 된 모든 조각을 단일 데이터 프레임으로 모아서 처리합니다.

library(plyr) 
df2 = ddply(df, .(x1, x2), function(d){ 
    limits = median(d$y) + 3*c(-1, 1)*mad(d$y) 
    d[(d$y - limits[1])*(limits[2] - d$y) > 0,] 
}) 
+0

처음에는'ddply'를 사용하려고 시도했지만 아무데도 없습니다. 설명 주셔서 감사합니다, 나는'플라이'를 조금 더 잘 사용하는 방법을 이해합니다. – luser

3

merge을 사용하고 표준 하위 집합을 사용할 수 있다고 가정합니다. 다음은 aggregate 문을 수정하여 merge을 좀 더 쉽게 작성하는 이름을 더 잘 나타냅니다. 또한 do.call(data.frame, ...)을 사용하여 매트릭스 열을 집계 된 열로 평평하게합니다. data.frame.

boundaries <- aggregate(y ~ x1 + x2, df, function(x) 
    cbind(median(x) + (3*mad(x)), median(x) - (3*mad(x)))) 
boundaries <- do.call(data.frame, boundaries) 

out <- merge(df, boundaries) 
head(out) 
# x1 x2   y  y.1  y.2 
# 1 a a -0.4003471 2.87556 -2.809068 
# 2 a a -0.5652717 2.87556 -2.809068 
# 3 a a 0.1185306 2.87556 -2.809068 
# 4 a a 1.2634333 2.87556 -2.809068 
# 5 a a 0.3585731 2.87556 -2.809068 
# 6 a a -0.1436202 2.87556 -2.809068 

out2 <- out[with(out, y.2 < y & y < y.1), c("y", "x1", "x2")] 
head(out2) 
#   y x1 x2 
# 1 -0.4003471 a a 
# 2 -0.5652717 a a 
# 3 0.1185306 a a 
# 4 1.2634333 a a 
# 5 0.3585731 a a 
# 6 -0.1436202 a a 

dim(out2) 
# [1] 1993 3 
+0

'R'은'Error in '[.default'(xj, i) : 처음에'경계를 만들려고 할 때'closure''라는 잘못된 첨자 유형을보고합니다. 무슨 일이 벌어 질지 몰라? – luser

+0

@luser, 실제 'data.frame'은 "df"입니까? 게시 한 샘플 데이터 세트에서 동일한 문제가 있습니까? – A5C1D2H2I1M1N2O1R2T1

+0

내 실제'data.frame'은'df' 또는 다른 시스템 예약 이름으로 불리지 않습니다. 내 작업 공간을 지우고 여기서 복사 한 코드를 복사하여 붙여 넣을 때도 동일한 문제가 발생합니다. – luser

0

이 함수는 결과 열이 불필요한 중간 재 계산 미친

filt <- function (x) { 
    b <- median(x) + mad(x) * c(-3, 3) 
    x[x > b[1] & x < b[2]] 
} 

집계하여 원래의 데이터 프레임을 방지하도록 구성하여 조건을 만족하는 값을 필터링 'Y'리스트 인 상기 필터 기준을 만족 -of-벡터

df1 <- aggregate(y ~ x1 + x2, df, filt, simplify=FALSE) 

표시기 변수는 최종 represe에 도달하도록, 복제, 및리스트의 벡터들을 미등록 정의

len <- sapply(df1$y, length) 
result <- data.frame(x1=rep(df1$x1, len), x2=rep(df1$x2, len), 
        y=unlist(df1$y, use.names=FALSE))