如何实现遍历DataFrame列并进行均值与回溯值异常检测?
批量检测DataFrame列异常值的函数实现
我懂啦,你需要把原来只能处理单列的函数改成能批量遍历DataFrame所有数值列的版本,同时保留和回溯2天值、列均值对比的逻辑对吧?下面我一步步帮你实现这个需求:
核心逻辑梳理
首先我们要明确处理规则:
- 跳过日期列(已知是升序无重复的
startdate),只处理数值列 - 对每个数值列:
- 计算该列的整体均值
- 获取每行回溯2天对应的值(利用日期升序的特性,用
lag函数直接取前2行的值) - 逐行判断:
- 当前值 > 回溯2天值 且 当前值 > 列均值 → 返回
"All okay" - 当前值 < 回溯2天值 且 当前值 < 列均值 → 返回
"Anomaly" - 其他情况(比如其中一个条件不满足,或前两行无回溯数据)返回
NA(可根据需求修改)
- 当前值 > 回溯2天值 且 当前值 > 列均值 → 返回
完整函数代码
我们用dplyr包来实现批量列处理,代码简洁且易读:
# 先加载必要的包 library(dplyr) check_anomalies <- function(df, date_col = "startdate") { # 筛选出所有数值列(排除指定的日期列) numeric_cols <- setdiff(names(df), date_col) # 提前计算每列的均值,避免重复计算 col_means <- sapply(df[numeric_cols], mean, na.rm = TRUE) # 批量处理每个数值列,生成对应的状态列 df_processed <- df %>% mutate( across( all_of(numeric_cols), .fns = function(x) { # 获取当前列的均值 current_mean <- col_means[[cur_column()]] # 获取回溯2天的值(前2行) lag_2_val <- lag(x, n = 2) # 执行判断逻辑 case_when( x > lag_2_val & x > current_mean ~ "All okay", x < lag_2_val & x < current_mean ~ "Anomaly", TRUE ~ NA_character_ # 其他情况返回NA,可自定义修改 ) }, .names = "{.col}_status" # 新列命名规则:原列名+_status ) ) return(df_processed) }
测试示例数据
用你提供的示例df来验证函数效果:
# 示例数据 df <- data.frame( startdate = as.Date('2010-11-1') + 0:4, salary = c(21000,23400,26800,40586,86750), bonus = c(350,400,170,180,95) ) # 运行函数 result <- check_anomalies(df) print(result)
输出结果
startdate salary bonus salary_status bonus_status 1 2010-11-01 21000 350 <NA> <NA> 2 2010-11-02 23400 400 <NA> <NA> 3 2010-11-03 26800 170 <NA> Anomaly 4 2010-11-04 40586 180 All okay Anomaly 5 2010-11-05 86750 95 All okay Anomaly
结果解释
- 前两行因为没有回溯2天的数据(
lag(2)返回NA),所以状态列为NA salary列第四、五行的值既大于回溯2天的值,又大于列均值(39707.2),所以返回"All okay"bonus列第三、四、五行的值既小于回溯2天的值,又小于列均值(239),所以返回"Anomaly"
适配你的数据集
对于你那30行14列的数据集:
- 如果日期列名不是
startdate,可以通过date_col参数指定,比如check_anomalies(your_df, date_col = "your_date_column") - 函数会自动识别所有数值列并批量处理,无需手动指定列名
- 如果数据中有缺失值,
mean函数的na.rm = TRUE会忽略缺失值计算均值,你可以根据需求调整缺失值的处理逻辑
内容的提问来源于stack exchange,提问作者Ekaterina
相关产品推荐
相关产品推荐

