如果从数据框中的每一列中检测到离群值(例如 99% 分位数),则删除完整行
Remove COMPLETE row if Outlier (e.g. 99% Quantile) is Detected from EVERY Column in a Dataframe
假设这是我的数据框。
MyData <- data.frame(
+ X = sample(10:100, 21),
+ Y = sample(10:100, 21),
+ Z = sample(10:100, 21)
+ )
我了解如何使用 sapply
或 apply
打印每列的分位数:
> apply( MyData , 2, quantile , .99 , na.rm = TRUE )
X Y Z
98.0 97.6 92.8
> sapply( MyData , quantile , .99 , na.rm = TRUE )
X.99% Y.99% Z.99%
98.0 97.6 92.8
但是,如果检测到高于此阈值的值,则删除整个 ROW(对于每个列都是如此)对我不起作用。任何解决方案 - 有或没有 dplyr
都表示赞赏。
这是一个使用 cut
的解决方案:
set.seed(123)
MyData <- data.frame(
X = sample(10:100, 21),
Y = sample(10:100, 21),
Z = sample(10:100, 21)
)
head(MyData, 4)
#> X Y Z
#> 1 36 73 47
#> 2 80 67 43
#> 3 46 98 23
#> 4 87 99 22
apply(MyData, 2, quantile, .95)
#> X Y Z
#> 97 98 83
tmp1 <- apply(MyData, 2, function(x) cut(x, c(-Inf, quantile(x, probs = .95), Inf), labels = FALSE))
MyData[tmp1 == 2] <- NA
head(MyData, 4)
#> X Y Z
#> 1 36 73 47
#> 2 80 67 43
#> 3 46 98 23
#> 4 87 NA 22
head(na.omit(MyData), 4)
#> X Y Z
#> 1 36 73 47
#> 2 80 67 43
#> 3 46 98 23
#> 5 91 71 30
您可以与分位数进行比较以获得 TRUE 和 FALSE 矩阵,然后对没有列包含 TRUE 的行进行子集化
MyData[!apply(apply(MyData, 2, function(x) x > quantile(x, 0.99)), 1, any), ]
数据:
set.seed(26L)
MyData <- as.matrix(data.frame(
X = sample(10:100, 21),
Y = sample(10:100, 21),
Z = sample(10:100, 21)
))
我们可以使用 dplyr
中的 filter_all
来为每一列的条件过滤行。 all_vars
表示所有列都满足条件。
set.seed(123)
MyData <- data.frame(
X = sample(10:100, 21),
Y = sample(10:100, 21),
Z = sample(10:100, 21)
)
head(MyData)
# X Y Z
# 1 36 73 47
# 2 80 67 43
# 3 46 98 23
# 4 87 99 22
# 5 91 71 30
# 6 13 56 50
library(dplyr)
MyData2 <- MyData %>% filter_all(all_vars(. <= quantile(., 0.99, na.rm = TRUE)))
head(MyData2)
# X Y Z
# 1 36 73 47
# 2 80 67 43
# 3 46 98 23
# 4 91 71 30
# 5 13 56 50
# 6 54 60 32
假设这是我的数据框。
MyData <- data.frame(
+ X = sample(10:100, 21),
+ Y = sample(10:100, 21),
+ Z = sample(10:100, 21)
+ )
我了解如何使用 sapply
或 apply
打印每列的分位数:
> apply( MyData , 2, quantile , .99 , na.rm = TRUE )
X Y Z
98.0 97.6 92.8
> sapply( MyData , quantile , .99 , na.rm = TRUE )
X.99% Y.99% Z.99%
98.0 97.6 92.8
但是,如果检测到高于此阈值的值,则删除整个 ROW(对于每个列都是如此)对我不起作用。任何解决方案 - 有或没有 dplyr
都表示赞赏。
这是一个使用 cut
的解决方案:
set.seed(123)
MyData <- data.frame(
X = sample(10:100, 21),
Y = sample(10:100, 21),
Z = sample(10:100, 21)
)
head(MyData, 4)
#> X Y Z
#> 1 36 73 47
#> 2 80 67 43
#> 3 46 98 23
#> 4 87 99 22
apply(MyData, 2, quantile, .95)
#> X Y Z
#> 97 98 83
tmp1 <- apply(MyData, 2, function(x) cut(x, c(-Inf, quantile(x, probs = .95), Inf), labels = FALSE))
MyData[tmp1 == 2] <- NA
head(MyData, 4)
#> X Y Z
#> 1 36 73 47
#> 2 80 67 43
#> 3 46 98 23
#> 4 87 NA 22
head(na.omit(MyData), 4)
#> X Y Z
#> 1 36 73 47
#> 2 80 67 43
#> 3 46 98 23
#> 5 91 71 30
您可以与分位数进行比较以获得 TRUE 和 FALSE 矩阵,然后对没有列包含 TRUE 的行进行子集化
MyData[!apply(apply(MyData, 2, function(x) x > quantile(x, 0.99)), 1, any), ]
数据:
set.seed(26L)
MyData <- as.matrix(data.frame(
X = sample(10:100, 21),
Y = sample(10:100, 21),
Z = sample(10:100, 21)
))
我们可以使用 dplyr
中的 filter_all
来为每一列的条件过滤行。 all_vars
表示所有列都满足条件。
set.seed(123)
MyData <- data.frame(
X = sample(10:100, 21),
Y = sample(10:100, 21),
Z = sample(10:100, 21)
)
head(MyData)
# X Y Z
# 1 36 73 47
# 2 80 67 43
# 3 46 98 23
# 4 87 99 22
# 5 91 71 30
# 6 13 56 50
library(dplyr)
MyData2 <- MyData %>% filter_all(all_vars(. <= quantile(., 0.99, na.rm = TRUE)))
head(MyData2)
# X Y Z
# 1 36 73 47
# 2 80 67 43
# 3 46 98 23
# 4 91 71 30
# 5 13 56 50
# 6 54 60 32