9

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

任何建议将不胜感激,我在其他任何地方都找不到有关如何执行此操作的任何信息。

4

4 回答 4

21

这样就可以了。

fun <- function(x){
    quantiles <- quantile( x, c(.05, .95 ) )
    x[ x < quantiles[1] ] <- quantiles[1]
    x[ x > quantiles[2] ] <- quantiles[2]
    x
}
fun( yourdata )
于 2012-11-12T07:32:47.910 回答
12

您可以使用以下代码在一行代码中完成squish()

d2 <- squish(d, quantile(d, c(.05, .95)))



在 scales 库中,查看?squish?discard

#--------------------------------
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
于 2012-11-12T08:01:18.647 回答
3

我用这段代码来得到你需要的东西:

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)})

df您的 data.frame 和value包含您的数据的列在哪里。

于 2012-11-12T07:34:22.627 回答
2

有更好的方法来解决这个问题。离群值不是超过 95% 或低于 5% 的任何点。相反,如果离群值低于第一个四分位数 – 1.5·IQR 或高于第三个四分位数 + 1.5·IQR,则视为异常值。
本网站将详细解释

要了解有关异常值处理的更多信息,请参阅此处

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
于 2018-12-26T03:50:24.337 回答