如何用R中的第5个和第95个百分位值替换异常值

如何用R中的第5个和第95个百分位值替换异常值,r,dataset,outliers,quantile,R,Dataset,Outliers,Quantile,我想用这些百分位值分别替换我相对较大的R数据集中高于第95百分位和低于第5百分位的所有值。我的目标是避免完全从数据中裁剪这些异常值 如果您有任何建议,我将不胜感激,我在其他地方找不到任何关于如何做到这一点的信息 这样就可以了 fun <- function(x){ quantiles <- quantile( x, c(.05, .95 ) ) x[ x < quantiles[1] ] <- quantiles[1] x[ x > quan

我想用这些百分位值分别替换我相对较大的R数据集中高于第95百分位和低于第5百分位的所有值。我的目标是避免完全从数据中裁剪这些异常值

如果您有任何建议,我将不胜感激,我在其他地方找不到任何关于如何做到这一点的信息

这样就可以了

fun <- function(x){
    quantiles <- quantile( x, c(.05, .95 ) )
    x[ x < quantiles[1] ] <- quantiles[1]
    x[ x > quantiles[2] ] <- quantiles[2]
    x
}
fun( yourdata )

fun我使用此代码获取您需要的:

qn = quantile(df$value, c(0.05, 0.95), na.rm = TRUE)
df = within(df, { value = ifelse(value < qn[1], qn[1], value)
                  value = ifelse(value > qn[2], qn[2], value)})
qn=分位数(df$value,c(0.05,0.95),na.rm=TRUE)
df=in(df,{value=ifelse(valueqn[2],qn[2],value)})

其中,
df
是您的data.frame,
value
是包含数据的列。

您可以使用
squish()在一行代码中完成此操作:

例如:

d <- 1:20
d
# [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20


d2 <- squish(d, round(quantile(d, c(.05, .95))))
d2
# [1]  2  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 19

有更好的方法来解决这个问题。异常值不是第95百分位以上或第5百分位以下的任何点。相反,如果异常值低于第一个四分位数–1.5·IQR或高于第三个四分位数+1.5·IQR,则视为异常值。


capOutlier除了需要更多的细节来回答这个问题之外,你真的确定要这样做吗?如果没有异常值,一个相对较大的数据集(比如100个数字)将有5个低于第5百分位的值和5个高于第95百分位的值。在采取这些措施时要特别小心,因为您正在急剧更改数据集的统计信息。这是否有效取决于您试图从数据中获取的内容以及数据的分布(例如,正态分布)。@RobS请小心使用
=
作为赋值运算符。我几乎总是使用
=
,而且我很少遇到麻烦。仅在调用中,如
system.time(bla Bobbo,缺失的细节将包括模型是什么以及如何定义百分位数;您是希望从数据中得出经验截止值,还是希望从模型中得出截止值,以及该模型是什么;具体而言,您希望如何替换数据点……使用模型参数替换为随机值?……其他一些插补形式?追溯到结尾?此外,你所做的并不是测试自身的稳健性。这需要添加一些其他内容。谢谢,工作起来就像做梦一样。我是这个网站的新手,有什么方法可以给你这个答案的代表或其他内容吗?你可以填写答案并接受它(你已经接受了)。如果您阅读了以上所有片段,请查看哪个片段也会给您一个徽章。上面的片段也会用分位数值替换NAs(如果有)。感谢您的回答,您的答案和上面的答案都很好。这是一个严格的离群值定义。您是否将离群值定义为低于20%/高于80%+(如您所定义)或低于5%/高于95%+(作为OP)是任意的;什么有效取决于您的问题和数据。我没有将其定义为低于20%或高于80%。我使用了一个离群值的通用定义,该定义可能会在《统计学导论》课程中使用。任何小于第一个四分位的值-1.5*四分位间距或大于第三个四分位+1.5*四分位间距为con定义了一个异常值。四分位数范围(IQR)是第一个四分位数和第三个四分位数(数据的中间50%)之间的范围。这不是一个“常见的”离群值的定义。这是一个任意的定义。如果你在大学上101统计学课,他们会给你关于离群值的定义。查看我答案中的网站。离群值还有其他定义,但这是最基本和最常用的定义。而且,我发布的定义比e问题中给出的一个。如果您有数据(.99998,1,1,1,1,1,1,1,1.0001),那么如果您使用问题中描述的离群值分类方法,.99998和1.0001将被错误地分类为离群值。尼斯。或者您可以将squish滚动到您自己的函数中。
cap
#--------------------------------
library(scales)

pr <- .95
q  <- quantile(d, c(1-pr, pr))
d2 <- squish(d, q)
#---------------------------------

# Note: depending on your needs, you may want to round off the quantile, ie:
q <- round(quantile(d, c(1-pr, pr)))
d <- 1:20
d
# [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20


d2 <- squish(d, round(quantile(d, c(.05, .95))))
d2
# [1]  2  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 19
capOutlier <- function(x){
   qnt <- quantile(x, probs=c(.25, .75), na.rm = T)
   caps <- quantile(x, probs=c(.05, .95), na.rm = T)
   H <- 1.5 * IQR(x, na.rm = T)
   x[x < (qnt[1] - H)] <- caps[1]
   x[x > (qnt[2] + H)] <- caps[2]
   return(x)
}
df$colName=capOutlier(df$colName)
Do the above line over and over for all of the columns in your data frame