如何删除数据框中任意列存在99%分位数异常值的整行?
解决方案:删除任意列超过对应99%分位数的行
这个需求其实很好实现,我给你两种方案——基础R原生语法和dplyr风格的写法,你可以根据自己的习惯选择:
方法一:基础R原生实现
首先我们先计算出每列的99%分位数阈值,然后按行检查是否所有列的数值都不超过对应阈值,保留符合条件的行:
# 先计算各列的99%分位数阈值 thresholds <- sapply(MyData, quantile, probs = 0.99, na.rm = TRUE) # 筛选出所有列都未超过对应阈值的行 MyData_filtered <- MyData[apply(MyData, 1, function(row) all(row <= thresholds)), ]
简单解释一下:
apply(MyData, 1, ...)是按行遍历数据框,对每一行执行后面的匿名函数- 匿名函数里的
all(row <= thresholds)用来判断当前行的所有元素是否都小于等于对应列的阈值,返回TRUE或FALSE - 最后用这个逻辑向量来筛选数据框的行,只保留返回
TRUE的行
方法二:dplyr实现(更简洁直观)
如果你习惯用tidyverse的风格,用dplyr可以写出更易读的代码:
# 先加载dplyr包 library(dplyr) # 直接在filter里结合across计算阈值并筛选 MyData_filtered <- MyData %>% filter(across(everything(), ~.x <= quantile(.x, probs = 0.99, na.rm = TRUE)))
或者如果你想先单独计算阈值再复用,也可以这么写:
# 先计算各列的99%分位数阈值 thresholds <- MyData %>% summarize(across(everything(), ~quantile(.x, probs = 0.99, na.rm = TRUE))) # 基于阈值筛选行 MyData_filtered <- MyData %>% filter(across(everything(), ~.x <= thresholds[[cur_column()]]))
这里的across(everything(), ...)会遍历所有列,对每列执行判断:当前列的数值是否小于等于该列的99%分位数,只有所有列都满足条件的行才会被保留。
内容的提问来源于stack exchange,提问作者Amir Rahbaran
相关产品推荐
相关产品推荐

