题
我有一些关于美丽与年龄的多元数据。年龄范围从 20 到 40 岁,间隔为 2(20、22、24....40),并且对于每条数据记录,都给出一个年龄和从 1 到 5 的美丽评级。当我绘制这些数据的箱线图(X 轴上的年龄,Y 轴上的美容评级)时,每个框的须线外部都绘制了一些异常值。
我想从数据框本身中删除这些异常值,但我不确定 R 如何计算其箱线图的异常值。下面是我的数据的示例。
解决方案
好的,您应该将类似的内容应用于您的数据集。不要替换并保存,否则您将破坏您的数据!而且,顺便说一句,您(几乎)永远不应该从数据中删除异常值:
remove_outliers <- function(x, na.rm = TRUE, ...) {
qnt <- quantile(x, probs=c(.25, .75), na.rm = na.rm, ...)
H <- 1.5 * IQR(x, na.rm = na.rm)
y <- x
y[x < (qnt[1] - H)] <- NA
y[x > (qnt[2] + H)] <- NA
y
}
要查看它的实际效果:
set.seed(1)
x <- rnorm(100)
x <- c(-10, x, 10)
y <- remove_outliers(x)
## png()
par(mfrow = c(1, 2))
boxplot(x)
boxplot(y)
## dev.off()
再说一次,你永远不应该自己这样做,异常值就是注定的!=)
编辑: 我添加了 na.rm = TRUE
作为默认值。
编辑2: 已删除 quantile
函数,添加了下标,因此使函数更快!=)
其他提示
没有人发布最简单的答案:
x[!x %in% boxplot.stats(x)$out]
另请参阅: http://www.r-statistics.com/2011/01/how-to-to-label-all-theelliers-in-a-boxplot/
利用 outline = FALSE
作为一个选择框图时的选项(阅读帮助!)。
> m <- c(rnorm(10),5,10)
> bp <- boxplot(m, outline = FALSE)
BoxPlot函数返回用于执行绘图的值(实际上是由BXP()完成的:
bstats <- boxplot(count ~ spray, data = InsectSprays, col = "lightgray")
#need to "waste" this plot
bstats$out <- NULL
bstats$group <- NULL
bxp(bstats) # this will plot without any outlier points
我故意没有回答具体问题,因为我认为删除“异常值”的统计渎职行为。我认为不要将它们绘制在箱形图中是可以接受的做法,但是仅仅因为它们超过了一定数量的标准偏差或一定数量的四分位间宽度是对观测记录的系统性和不科学的杂交。
x<-quantile(retentiondata$sum_dec_incr,c(0.01,0.99))
data_clean <- data[data$attribute >=x[1] & data$attribute<=x[2],]
我发现这很容易删除异常值。在上面的示例中,我只是提取属性值的2%至98%。
我查找了与删除异常值有关的软件包,并找到了这个软件包(出人意料地称为“离群值”!): https://cran.r-project.org/web/packages/outliers/outliers.pdf
如果您经历了它,您会看到不同的删除异常值的方法,其中我发现 rm.outlier
最方便的使用方法,正如上面的链接中所述:“如果通过统计测试检测并确认了离群值,则此功能可以将其删除或通过样本平均值或中位数替换”,这也是从同一源的使用部分:
"用法
rm.outlier(x, fill = FALSE, median = FALSE, opposite = FALSE)
参数
X 数据集,最常是向量。如果参数是一个数据框,则SAPPLY从每列删除离群值。给出矩阵时,应用相同的行为。
充满 如果设置为true,则位置或平均值将是放置而不是离群值。否则,简单删除了异常值。
中位数 如果设置为true,则使用中位数而不是均值在异常值替换中。如果设置为true,则给出相反的值(如果最大值与平均值具有最大差异,则给出最小的,反之亦然)”
不会:
z <- df[df$x > quantile(df$x, .25) - 1.5*IQR(df$x) &
df$x < quantile(df$x, .75) + 1.5*IQR(df$x), ] #rows
很容易完成此任务?
添加到@sefarkas的建议中并使用分位数作为截止值,可以探索以下选项:
newdata <- subset(mydata,!(mydata$var > quantile(mydata$var, probs=c(.01, .99))[2] | mydata$var < quantile(mydata$var, probs=c(.01, .99))[1]) )
这将删除第99个分位数以外的点。应该像AL3XA有关保持离群值的说法一样注意。应将其仅用于获取数据的替代保守视图。
尝试这个。将您的变量馈送到功能中,并将O/P保存在包含删除离群值的变量中
outliers<-function(variable){
iqr<-IQR(variable)
q1<-as.numeric(quantile(variable,0.25))
q3<-as.numeric(quantile(variable,0.75))
mild_low<-q1-(1.5*iqr)
mild_high<-q3+(1.5*iqr)
new_variable<-variable[variable>mild_low & variable<mild_high]
return(new_variable)
}