[英]Using results of aggregate to subset data in R
我正在使用R
的stats
包中的mad
函數來識別異常值。 使用aggregate
,我可以找到因子水平的每個唯一組合的邊界值,如下所示:
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
是下限。 我想對df
進行子集處理,以便針對每種因子水平組合刪除異常值-例如,在aa中,我不希望任何高於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)))),])
任何指導是非常感謝。
我想您可以使用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
這是使用plyr
的解決方案。 它使用split-apply-combine范例。 我們首先使用x1
和x2
列將數據幀分成多個部分。 對於每個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,]
})
此函數過濾值以滿足您的條件,其結構避免不必要地重新計算中值和瘋狂
filt <- function (x) {
b <- median(x) + mad(x) * c(-3, 3)
x[x > b[1] & x < b[2]]
}
匯總原始數據幀,結果列“ y”是滿足過濾條件的向量列表
df1 <- aggregate(y ~ x1 + x2, df, filt, simplify=FALSE)
然后復制指標變量,並且不列出向量列表,以得出最終表示形式
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))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.