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

如何实现遍历DataFrame列并进行均值与回溯值异常检测?

批量检测DataFrame列异常值的函数实现

我懂啦,你需要把原来只能处理单列的函数改成能批量遍历DataFrame所有数值列的版本,同时保留和回溯2天值、列均值对比的逻辑对吧?下面我一步步帮你实现这个需求:

核心逻辑梳理

首先我们要明确处理规则:

  • 跳过日期列(已知是升序无重复的startdate),只处理数值列
  • 对每个数值列:
    1. 计算该列的整体均值
    2. 获取每行回溯2天对应的值(利用日期升序的特性,用lag函数直接取前2行的值)
    3. 逐行判断:
      • 当前值 > 回溯2天值 且 当前值 > 列均值 → 返回"All okay"
      • 当前值 < 回溯2天值 且 当前值 < 列均值 → 返回"Anomaly"
      • 其他情况(比如其中一个条件不满足,或前两行无回溯数据)返回NA(可根据需求修改)

完整函数代码

我们用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:43:15