我对R很陌生,以至于我无法在其他人的问题中找到我需要的东西。我认为我的问题非常简单,没有其他人愿意提出这个问题。
创建一个新数据框的最简单的代码是什么,它排除了单变量异常值的数据(我将它们定义为从它们的条件的平均值为3个SD的点),在它们的条件下,在某个变量上? / p>
我很尴尬地展示我尝试过的东西,但这里是
greaterthan <- mean(dat$var2[dat$condition=="one"]) +
2.5*(sd(dat$var2[dat$condition=="one"]))
lessthan <- mean(dat$var2[dat$condition=="one"]) -
2.5*(sd(dat$var2[dat$condition=="one"]))
withoutliersremovedone1 <-dat$var2[dat$condition=="one"] < greaterthan
我几乎已经被困在那里了。
由于
答案 0 :(得分:7)
> dat <- data.frame(
var1=sample(letters[1:2],10,replace=TRUE),
var2=c(1,2,3,1,2,3,102,3,1,2)
)
> dat
var1 var2
1 b 1
2 a 2
3 a 3
4 a 1
5 b 2
6 b 3
7 a 102 #outlier
8 b 3
9 b 1
10 a 2
现在只返回那些不是(!
)大于2 abs
olute sd
的行,而是从相关变量的mean
开始。显然,将2更改为您希望成为截止日期的sd
。
> dat[!(abs(dat$var2 - mean(dat$var2))/sd(dat$var2)) > 2,]
var1 var2
1 b 1
2 a 2
3 a 3
4 a 1
5 b 2
6 b 3 # no outlier
8 b 3 # between here
9 b 1
10 a 2
使用scale
功能更简洁:
dat[!abs(scale(dat$var2)) > 2,]
var1 var2
1 b 1
2 a 2
3 a 3
4 a 1
5 b 2
6 b 3
8 b 3
9 b 1
10 a 2
修改强>
这可以扩展到使用by
do.call(rbind,by(dat,dat$var1,function(x) x[!abs(scale(x$var2)) > 2,] ))
这假定dat$var1
是定义每行所属组的变量。
答案 1 :(得分:4)
我使用robustHD包中的winsorize()
函数执行此任务。这是它的例子:
R> example(winsorize)
winsrzR> ## generate data
winsrzR> set.seed(1234) # for reproducibility
winsrzR> x <- rnorm(10) # standard normal
winsrzR> x[1] <- x[1] * 10 # introduce outlier
winsrzR> ## winsorize data
winsrzR> x
[1] -12.070657 0.277429 1.084441 -2.345698 0.429125 0.506056
[7] -0.574740 -0.546632 -0.564452 -0.890038
winsrzR> winsorize(x)
[1] -3.250372 0.277429 1.084441 -2.345698 0.429125 0.506056
[7] -0.574740 -0.546632 -0.564452 -0.890038
winsrzR>
默认为中位数+/- 2 mad,但您可以设置平均值+/- 3 sd的参数。