You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何批量将数据框数值列的异常值替换为列中位数?

批量替换数据集中所有数值列的异常值

我有一个包含分类变量与数值变量的数据集,希望用箱线图识别异常值并替换为对应列的中位数,但需要批量处理所有数值列,而非逐个列手动操作。单列处理的参考代码如下:

df$v3[df$v3 %in% boxplot(df)$out] <- median(df$v3)

数据集结构:

df<-structure(list(`Project Title` = c("Cameroun - Projet d’aide humanitaire d’urgence en faveur des réfugiés hors sites et des populations hôtes situés dans les régions de l’Adamaoua, de l’Est et du Nord\r\n(Version française uniquement)", 
"Multinational - Kenya-Tanzania Power Interconnection Project", 
"Multinational - Kenya-Tanzania Power Interconnection Project", 
"Zambia - Madison Finance Company Limited\r\n(under the Africa SME Program)", 
"Eritrea - Skills Development for Employability and Entrepreneurship Project", 
"Eritrea - Skills Development for Employability and Entrepreneurship Project", 
"Uganda - Water Supply and Sanitation Programme - Additional activities", 
"Cabo Verde - Aide d’urgence pour assister les populations affectées par l’éruption volcanique de l’île de Fogo\r\n(Version française uniquement)", 
"Kenya - Mombasa-Mariakani Highway Project", "Multinational - Africa Banking Corporation Holdings Ltd"
), `Approval date Year Trend` = structure(c(1421107200, 1424217600, 
1424217600, 1425254400, 1425340800, 1425340800, 1425427200, 1425600000, 
1426032000, 1426032000), tzone = "UTC", class = c("POSIXct", 
"POSIXt")), `Type of Financing Source` = c("Special Relief Fund (SRF)", 
"ADF", "ADF", "ADB Private Sector", "ADF", "ADF", "Global Environment Facility (GEF)", 
"Special Relief Fund (SRF)", "ADF", "ADB Private Sector"), `Approved Amount_UA Equivalent` = c(690221.630165446, 
75290000, 27500000, 2131605.31196044, 7580000, 5920000, 5947178.82036962, 
191844.478076439, 8e+07, 11842251.7331135), `Approved Amount_USDEquivalent` = c(920065.43301054, 
100361570, 36657500, 2841429.88084326, 10104140, 7891360, 7927589.3675527, 
255728.689275894, 106640000, 15785721.5602403), `Project ID` = c("P-CM-I00-001", 
"P-Z1-FA0-052", "P-Z1-FA0-086", "P-ZM-HAB-003", "P-ER-IA0-001", 
"P-ER-IA0-001", "P-UG-E00-013", "P-CV-I00-001", "P-KE-DB0-021", 
"P-Z1-HAB-046"), `Employe Name` = c("BISSAKONOU Judes", "MUGUWA Andrew", 
"MUGUWA Andrew", "FRENCH Laura Katherine Smith", "ELAHEEBOCUS Bibi Nawsheen", 
"ELAHEEBOCUS Bibi Nawsheen", "MBIRO Andrew", "TRAORE Rokhaya", 
"MAMMO Zerfu Tessema", "MACHARIA Julius Karuga"), `Financing Source` = c("OTHERS", 
"ADF Including TSF", "ADF Including TSF", "ADB Private", "ADF Including TSF", 
"ADF Including TSF", "OTHERS", "OTHERS", "ADF Including TSF", 
"ADB Private"), `Financial Access Category` = c("Blend Countries", 
"Multinational", "Blend Countries", "Blend Countries", "ADF Countries", 
"ADF Countries", "ADF Countries", "ADB Countries", "Blend Countries", 
"Multinational"), `Country Classifaction` = c("Non-Transition States", 
"Multinational", "Non-Transition States", "Non-Transition States", 
"Transition States", "Transition States", "Non-Transition States", 
"Non-Transition States", "Non-Transition States", "Multinational"
), `Country Name` = c("CAMEROON", "MULTINATIONAL", "KENYA", "ZAMBIA", 
"ERITREA", "ERITREA", "UGANDA", "Cape Verde", "KENYA", "MULTINATIONAL"
), `REGION NAME` = c("Central", "Multinational", "East", "South", 
"East", "East", "East", "West", "East", "Multinational"), `Sectoral Analysis` = c("Social", 
"Power", "Power", "Finance", "Social", "Social", "WASH Sector", 
"Social", "Transport", "Finance"), `High Five Prority 1: Feed Africa` = c(NA, 
NA, NA, NA, NA, NA, 178415.364611089, NA, NA, NA), `High Five Prority 2: Light Up And Power Africa` = c(NA, 
75290000, 27500000, NA, NA, NA, 59471.7882036962, NA, NA, NA), 
    `High Five Prority 3: Industrialize Africa` = c(NA, NA, NA, 
    2131605.31196044, NA, NA, NA, NA, NA, 11842251.7331135), 
    `High Five Prority 4: Integrate Africa` = c(NA, NA, NA, NA, 
    NA, NA, NA, NA, 8e+07, NA), `High Five Prority 5: Improve Quality Of Life` = c(690221.630165446, 
    NA, NA, NA, 7580000, 5920000, 5709291.66755484, 191844.478076439, 
    NA, NA), `Financing Instrument` = c("Emergency Assistance", 
    "Investment Project", "Investment Project", "Investment Project", 
    "Investment Project", "Investment Project", "ISP and Investment Project", 
    "Emergency Assistance", "Investment Project", "Investment Project"
    ), `Infrastructure vs Sector` = c("Social", "Infrastructure", 
    "Infrastructure", "Finance", "Social", "Social", "Infrastructure", 
    "Social", "Infrastructure", "Finance"), `SECTOR DEPARTMENT` = c("AHAI", 
    "PESD", "PESD", "PIFD", "AHHD", "AHHD", "AHWS", "AHHD", "PICU", 
    "PIFD"), `Sector Complex Name` = c("AHVP", "PEVP", "PEVP", 
    "PIVP", "AHVP", "AHVP", "AHVP", "AHVP", "PIVP", "PIVP"), 
    `Operations Type` = c("Sovereign", "Sovereign", "Sovereign", 
    "Non-Sovereign", "Sovereign", "Sovereign", "Sovereign", "Sovereign", 
    "Sovereign", "Non-Sovereign"), `NUMBER OF PROJECT` = c(1, 
    1, 1, 1, 0.5, 0.5, 1, 1, 1, 1), `Amount in UA Million` = c(0.690221630165446, 
    75.29, 27.5, 2.13160531196044, 7.58, 5.92, 5.94717882036962, 
    0.191844478076439, 80, 11.8422517331135)), row.names = c(NA, 
-10L), class = c("tbl_df", "tbl", "data.frame"))

解决方案

方法1:Base R 批量处理

通过lapply遍历所有数值列,自动完成异常值识别与替换:

# 筛选所有数值类型的列
numeric_cols <- sapply(df, is.numeric)

# 对每个数值列执行异常值替换
df[numeric_cols] <- lapply(df[numeric_cols], function(col) {
  # 不绘制箱线图,仅获取异常值列表
  outliers <- boxplot(col, plot = FALSE)$out
  # 计算列的中位数(忽略缺失值)
  col_median <- median(col, na.rm = TRUE)
  # 将异常值替换为中位数
  col[col %in% outliers] <- col_median
  return(col)
})

方法2:tidyverse/dplyr 风格实现

如果使用tidyverse工具链,用across函数可以更简洁地批量处理:

library(dplyr)

df_clean <- df %>%
  mutate(across(where(is.numeric), ~{
    outliers <- boxplot(., plot = FALSE)$out
    median_val <- median(., na.rm = TRUE)
    # 替换异常值
    replace(., . %in% outliers, median_val)
  }))

关键细节说明

  • plot = FALSE:避免每次处理列都弹出箱线图,仅返回异常值数据
  • na.rm = TRUE:计算中位数时自动忽略缺失值,避免结果出错
  • 两种方法都会保留原数据集的分类列,仅修改数值列的异常值

内容的提问来源于stack exchange,提问作者firmo23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 10:52:04