当前数据帧由数值组成。 我正在逐列识别数据框中的异常值, 我可以一次在列中识别异常值并一次性删除它们吗? 现在我将值更改为NA
我的代码:
quantiles<-tapply(var1,names,quantile)
minq <- sapply(names, function(x) quantiles[[x]]["25%"])
maxq <- sapply(names, function(x) quantiles[[x]]["75%"])
var1[var1<minq | var1>maxq] <- NA
数据。
OP以dput
格式以注释形式发布的数据。
df1 <-
structure(list(Var1 = c(100.2, 110, 200, 456, 120000),
var2 = c(NA, 4545L, 45465L, 44422L, 250000L),
var3 = c(NA, 210000L, 91500L, 215000L, 250000L),
var4 = c(0.983, 0.44, 0.983, 0.78, 2.23)),
class = "data.frame", row.names = c(NA, -5L))
答案 0 :(得分:0)
以下内容从数据帧中删除了异常值,但结果是一个列表,而不是数据帧,因为生成的向量的长度并不都相同。
df2 <- lapply(df1, function(x){
qq <- quantile(x, c(0.25, 0.75), na.rm = TRUE)
x[!is.na(x) & qq[1] <= x & x <= qq[2]]
})
修改
在this question之后跟随相同的@user11368874,下面的代码受上面第一个代码的启发,并回答了第二个问题。
df3 <- df1
df3[] <- lapply(df1, function(x){
qq <- quantile(x, c(0.25, 0.75), na.rm = TRUE)
is.na(x) <- x < qq[1] | x > qq[2]
x
})
df3
# Var1 var2 var3 var4
#1 NA NA NA 0.983
#2 110 NA 210000 NA
#3 200 45465 NA 0.983
#4 456 44422 215000 0.780
#5 NA NA NA NA
答案 1 :(得分:0)
以下功能测试,列中的哪些值在Tukey的防护范围之外(第一和第三四分位数下方和上方的异常值)。然后,根据用户的喜好,该函数使用离群值删除包含任何值的所有行,或将离群值替换为NA
。
outlier.out <- function(dat, q = c(0.25, 0.75), out = TRUE){
# create a place for identification of outliers
tests <- matrix(NA, ncol = ncol(dat), nrow = nrow(dat))
# test, which cells contain outliers, ignoring existing NA values
for(i in 1:ncol(dat)){
qq <- quantile(dat[, i], q, na.rm = TRUE)
tests[, i] <- sapply(dat[, i] < qq[1] | dat[, i] > qq[2], isTRUE)
}
if(out){
# removes lines with outliers
dat <- dat[!apply(tests, 1, FUN = any, na.rm = TRUE) ,]
} else {
# replaces outliers with NA
dat[tests] <- NA
}
return(dat)
}
outlier.out(df1)
# Var1 var2 var3 var4
# 4 456 44422 215000 0.78
outlier.out(df1, out = FALSE)
# Var1 var2 var3 var4
# 1 NA NA NA 0.983
# 2 110 NA 210000 NA
# 3 200 45465 NA 0.983
# 4 456 44422 215000 0.780
# 5 NA NA NA NA